On Thu, Aug 24, 2000 at 03:37:59PM -0000, Perl6 RFC Librarian wrote:
> =head1 TITLE
>
> Omnibus Structured Exception/Error Handling Mechanism
Woohoo!
> catch Alarm => { ... }
> catch Alarm, Error => { ... }
> catch $@ =~ /divide by 0/ => { ... }
The => here seems like useless syntax to me.
> try { ... }
> catch MatchThis => { ... }
> catch MatchThat => { ... }
> catch { ... } # everything else
> finally { ... }
Let me tell you some semantics and syntax that I've thought of ...
they're remarkably similar to yours ;-)
try { ... } # For every one of these, we have
catch BAREWORD { ... } # zero or more catch clauses
catch METHOD { ... }
catch LIST { ... }
catch EXPR { ... }
catch { ... }
finally { ... } # and exactly zero or one of these
If the target of a catch is a BAREWORD or a string, it is taken to be
a class name and act as if $@->isa(BAREWORD) or $@->isa(STRING) were
invoked. If the isa() is true, the block executes.
If catch is given a METHOD (subroutine), it's evaluated as if
$@->METHOD were executed (with whatever arguments). If no such method
exists in the exception hierarchy for the thrown exception, it's taken
to be a normal subroutine and just executed. If the METHOD or
subroutine evaluate to true, the block is executed. (To force Perl to
treat it as a subroutine in the current package, explicitly qualify
it. I expect this usage to be rare, but I could be wrong.)
If catch has a LIST, each element of the list is evaluated as above
and if *any* of them return true, the catch block executes.
Otherwise, any arbitrary expression can be evaluated for truthness.
And C<catch { ... }>, of course, catches any exception. And C<finally
{ ... }> is always executed no matter what.
Upon completion of a catch block, the exception is considered handled.
If the catch block contains C<throw;> the current exception is kept on
the stack for subsequent catch blocks to deal with. Quick example:
try { 23 / 0 } # throws Math::DivideByZero
catch Math::DivideByZero { ... throw; } # not handled
catch Math::DivideByZero { ... } # handled.
finally { ... } # end processing.
A C<throw> inside of one of the catch blocks simply pushes the
exception on the stack and subsequent catch blocks get a chance to
handle it. If none of the catch clauses handle the exception, it's
propigated to the next enclosing exception handler after the finally
block is executed.
> If multiple statements are required to compute the value of the
> EXPR, use this form: catch do { a; b } => { ... }
Or how about just this:
catch { a; b } { ... }
Yes, I realize some hoops may have to be jumped through to
distinguish these:
catch { ... } # all exceptions
{ ... } # random code, Oops!
catch { ... } { ... } # catch only if the first block is true
But that's what computers are for!
No, now that I think about it, requiring the C<do> is best:
catch do { ... } { ... }
But that => still seems superfluous to me.
> The "try" is not for Perl's sake. It's for the developer's
> sake. It says, watch out, some sort of non-local flow control
> is going on here. It signals intent to deal with action at a
> distance (unwinding semantics). It satisfies the first rule
> listed under L<MOTIVATION>.
Hmm ... I wonder if there's a way we can tell builtins (like open)
that they are to throw exceptions if they appear in try blocks?
> Syntax
>
> The comma or => in the catch clause is required so the
> expression can be parsed from the block, in the fashion
> of Perl 5's C<map expression, list>;
You mean like this?
@doubles = map { $_*2 } @numbers;
I don't see a comma or => in there at all ;-)
> Lexical Scope
>
> The authors would prefer that try, catch, and finally blocks
> share the same lexical scope.
A few of us random commentators agree with this as well.
my $cents = 2;
-Scott
--
Jonathan Scott Duff
[EMAIL PROTECTED]