|
From: Maciej Sobczak on 15 Jan 2007 08:44 Hi, Consider an object created by a constructor function: X : My_Type := My_Constructor(Some_Parameters); My_Type is Controlled_Limited to ensure control over initialization and finalization. The idea of constructor function is to prevent the existence of objects that are not yet initialized, half-baked, in a bad state, etc. If the object exists, it's ready for use. If there are problems during the execution of the constructor function, the exception is raised, so that there is no X object in a bad state. How can I pass some error information from the constructor function out, so that it's used when the exception is handled? Obviously, some message can be attached to the exception occurence, but it doesn't scale well - I might want to pass some more data, possibly structured (some error code, some reason code, some timestamp, some whatever else, ...). Yes, I'm asking for "throwing objects", in the C++ parlance. How to do this in Ada? If I cannot - how to solve this design problem? BTW - How can I ensure in a general way that the constructor function must be used to initialize the object, otherwise compile-time error is reported? If I make My_Type a discriminated type (so that the discriminant value is used in the default initialization), does it limit anything, like constructor parameter types? -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/
From: claude.simon on 15 Jan 2007 12:17 when My_Type is an indefinite subtype. type My_type (<>) is ... for example Then, when you declare an object of that type you must provide an initialization expression (a constructor call !). Maciej Sobczak a écrit : > Hi, > > Consider an object created by a constructor function: > > X : My_Type := My_Constructor(Some_Parameters); > > My_Type is Controlled_Limited to ensure control over initialization and > finalization. The idea of constructor function is to prevent the > existence of objects that are not yet initialized, half-baked, in a bad > state, etc. If the object exists, it's ready for use. > > If there are problems during the execution of the constructor function, > the exception is raised, so that there is no X object in a bad state. > How can I pass some error information from the constructor function out, > so that it's used when the exception is handled? > Obviously, some message can be attached to the exception occurence, but > it doesn't scale well - I might want to pass some more data, possibly > structured (some error code, some reason code, some timestamp, some > whatever else, ...). > > Yes, I'm asking for "throwing objects", in the C++ parlance. > > How to do this in Ada? > If I cannot - how to solve this design problem? > > BTW - How can I ensure in a general way that the constructor function > must be used to initialize the object, otherwise compile-time error is > reported? > If I make My_Type a discriminated type (so that the discriminant value > is used in the default initialization), does it limit anything, like > constructor parameter types? > > -- > Maciej Sobczak : http://www.msobczak.com/ > Programming : http://www.msobczak.com/prog/
From: Robert A Duff on 15 Jan 2007 12:28 Maciej Sobczak <no.spam(a)no.spam.com> writes: > If there are problems during the execution of the constructor function, > the exception is raised, so that there is no X object in a bad state. > How can I pass some error information from the constructor function out, > so that it's used when the exception is handled? There is no good way to do this in Ada. You can attach any information you like to an exception, if you are willing to encode it as a String -- but then you lose static type checking. You can put the info in a global variable, but that's bad for several reasons (not task safe, can be accessed outside of any handler, ...). You can put the info in a Task_Attribute, but that's rather a pain -- verbose and inefficient. - Bob
From: Georg Bauhaus on 15 Jan 2007 13:29 On Mon, 2007-01-15 at 12:28 -0500, Robert A Duff wrote: > Maciej Sobczak <no.spam(a)no.spam.com> writes: > > > If there are problems during the execution of the constructor function, > > the exception is raised, so that there is no X object in a bad state. > > How can I pass some error information from the constructor function out, > > so that it's used when the exception is handled? > > There is no good way to do this in Ada. You can attach any information > you like to an exception, if you are willing to encode it as a String -- > but then you lose static type checking. You can put the info in a > global variable, but that's bad for several reasons (not task safe, > can be accessed outside of any handler, ...). You can put the info in a > Task_Attribute, but that's rather a pain -- verbose and inefficient. I'm still wondering whether or not an Ada compiler could provide a special kind of closure for this case? We do already get stack traces. (I don't know compilers so this is just a guess...) package Handling is -- -- info to be attached to an exception occurence -- type State is tagged record info: Integer; end record; end Handling; with Handling; use Handling; procedure foo is x: Integer; function Env return State'class is begin return State'(info => x); end Env; begin if 1 > 1 then raise Constraint_Error with Env'access; end if; end foo;
From: Dmitry A. Kazakov on 15 Jan 2007 14:44
On Mon, 15 Jan 2007 19:29:31 +0100, Georg Bauhaus wrote: > On Mon, 2007-01-15 at 12:28 -0500, Robert A Duff wrote: >> Maciej Sobczak <no.spam(a)no.spam.com> writes: >> >>> If there are problems during the execution of the constructor function, >>> the exception is raised, so that there is no X object in a bad state. >>> How can I pass some error information from the constructor function out, >>> so that it's used when the exception is handled? >> >> There is no good way to do this in Ada. You can attach any information >> you like to an exception, if you are willing to encode it as a String -- >> but then you lose static type checking. You can put the info in a >> global variable, but that's bad for several reasons (not task safe, >> can be accessed outside of any handler, ...). You can put the info in a >> Task_Attribute, but that's rather a pain -- verbose and inefficient. > > I'm still wondering whether or not an Ada compiler could provide > a special kind of closure for this case? When closures should be supported then they should not be any special... > We do already get stack > traces. (I don't know compilers so this is just a guess...) > > package Handling is > > -- > -- info to be attached to an exception occurence > -- > > type State is tagged record > info: Integer; > end record; > > end Handling; > > > with Handling; use Handling; > procedure foo is > > x: Integer; > > function Env return State'class is > begin > return State'(info => x); > end Env; > > begin > if 1 > 1 then > raise Constraint_Error with Env'access; > end if; > end foo; Ada 2005 will allow non-library-level extensions. So? What if Env were declared within Foo? Exceptions are usually considered as non-local jumps. But there is also another mental model possible. One could consider them as a kind of rendezvous with the handler. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de |