At 12:35 AM 8/15/00 -0600, Tony Olekshy wrote:
>What if we implemented something like the following?
> finally { ... }
>
> Invoked whether or not unwinding. If the finally block
> throws then unwinding starts or continues, if finally
> doesn't throw then the unwinding state is not changed.
> Inside the finally block, $@ is the last raised exception
> if unwinding, and undef if not unwinding.
>
> catch { ... }
>
> Invoked if unwinding. This is a post-finally catch, but
> otherwise it can have all the syntax of other catches.
> If the catch block doesn't throw then unwinding stops.
What's this for? If the finally block throws?
> There can be any combination of catches and finallys; don't
> use combinations you don't like.
>
> When all the clauses are complete, if the unwinding state is
> set then the last raised exception is re-thrown, otherwise
> execution continues with the next statement.
>
>This is (I believe) very similar to RFC 63 syntax, other than the
>addition of "except", and fact that throw is not a constructor (you
>must pass throw a constructed exception, if that's what you want),
>so people can still say things like throw "Can't open $file.";
Hmm. I guess I would do that either with
throw Exception(message => "Can't open $file");
or
die "Can't open $file"
which RFC 63 says (under IMPLEMENTATION) should be the same thing.
>The semantics for clause flow control is also different from that
>in RFC 63, but only in the more complex cases.
>
>Now say throw wraps up it's argument in an Exception object unless
>it already isa Exception object. $@ or equivalent contains the
>current exception (but a linked list of previous exceptions raised
>since unwinding started is kept via a _link attribute in the
>Exception objects, which you can ignore except in the case of the
>"any" method described below, or if you want to generate a formatted
>unwind stack to show the user).
You're actually talking about something else, I think, but I think we
should do both.
You want: while handling an exception, throwing another exception pushes
the first one onto a stack which could be reported en masse when the coup
de gras arrives. Like VMS error cascading. You do this with a _link
attribute of exceptions. Cool, I can dig that.
I want: exceptions to contain 'file' and 'line' attributes which are arrays
that get a location pushed on every time an exception bubbles up through a
scoping level, so that e.g.:
main.pl:
1 try {
2 foo($obj);
3 };
4 sub foo {
5 $_[0]->bar();
6 }
Foo.pm:
100 sub bar {
101 pling(shift);
102 }
103 sub pling {
104 throw Exception::Baz unless blech(shift);
that by the time the exception percolates to the outermost level, the
attributes contain:
file line
Foo.pm 104
Foo.pm 101
main.pl 2
I think we should have both.
> except { $@->isa("Foo") and $@->CanBar }
>
> This handles exception object predicates added by extending
> the Exception base class.
>
>If I'm not mistaken, that lets me do everything RFC 88 does, it is
>more regular and directly extensible, and it still leaves the option
>for unwind stack formatting via the internal links.
I can go for that.
I think we're nearly at a consensus here.
--
Peter Scott
Pacific Systems Design Technologies