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

Reply via email to