From: Maciej Sobczak on
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
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
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
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
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