Tony,
Having done the exercise of redoing all your RFC 88 examples into RFC 119
syntax, I conclude that the two biggest differences between the syntaxes is
the explicit or implicit try, which is mostly an irrelevant placeholder;
some like it, some don't.
The biggest syntax simplifications came in examples that actually did
something, rather than being framework code demonstrating the syntax of the
features in the RFC.
I found one inconsistency in my understanding of the try/catch/finally/catch
sequence, noted below.
In any place where the goal is to catch fatal errors, I made the assumption
that somewhere close to where the fatal error was generated, that it was
trapped and wrapped into a throw of a single string message.
Perl6 RFC Librarian wrote:
> try {
> throw Alarm "a message", tag => "ABC.1234", ... ;
> }
>
> catch Alarm => { ... }
>
> catch Alarm, Error => { ... }
>
> catch $@ =~ /divide by 0/ => { ... }
>
> catch { ... }
>
> finally { ... }
{
throw Alarm "a message", tag => "ABC.1234", ... ;
catch Alarm => { ... }
catch Alarm, Error => { ... }
catch $_[0] => /divide by 0/ => { ... }
catch { ... }
} always { ... }
> The most common forms of structured exception handling are straight-
> forward. Here they are:
>
> try { ... } catch { ... }
{ ... ; catch { ... }}
> try { ... } finally { ... }
{ ... } always { ... }
or
... always ...
for simple varieties of ...
> try { ... }
> catch MatchThis => { ... }
> catch MatchThat => { ... }
> catch { ... } # everything else
> finally { ... }
{ ...
catch MatchThis => { ... }
catch MatchThat => { ... }
catch { ... } # everything else
} always { ... };
> try { fragile(); } catch { } # Go on no matter what.
{ fragile(); catch {}}
> try { ... }
> finally { ... }
> finally { ... }
{ ... } always { ... } always { ... }
or, for simple versions of ...
... always ... always ...;
> try { ... }
> catch { ... }
> finally { ... }
> catch { ... }
This is a rather obscure case. I'm really not sure how consistent it is
with the earlier statement that "Once a catch clause matches, subsequent
catch clauses are skipped (like elsif/elsif/else)." because here, the claim
is that the 2nd catch block can catch a throw from any of the three earlier
blocks, where the 2nd block is a catch block that should fail into the case
of the prior statement. But we'll try converting it to RFC 119 syntax as
follows:
{{ ... } always { ... }; catch { ... }}
catch { ... }
> throw Exception::IO "a message", tag => "ABC.1234", ... ;
throw Exception::IO "a message", tag => "ABC.1234", ... ;
> throw MyError "ABC.1234: A message.";
throw MyError "ABC.1234: A message.";
> try { ... } catch EXPR => { ... } finally { ... }
try { ... } catch EXPR { ... } finally { ... }
RFC 119 hasn't presupposed that the => is really necessary in a perl6
parser. Maybe it is, and maybe it isn't. Not a big deal to me, though.
> try { my $fh = open $file }
> finally { $fh and close $fh }
my $fh = open $file always close $fh;
> =head2 Examples
>
> The first three of these examples cover the most common uses of
> try, catch, and finally.
>
> try { my $f = open "foo"; ... } finally { $f and close $f; }
my $f = open "foo" always close $f; ...
> try { fragile(); } catch { print "$@\n"; }
{ fragile(); catch { print "@_"; }}
> try { ... }
> catch Exception::Foo => { ... }
> finally { ... }
{
{ ... } always { ... };
catch Exception::Foo { ... }
}
> sub AttemptClosureAfterSuccessfulCandidateFileOpen
> {
> my ($closure, @fileList) = @_; local (*F);
> foreach my $file (@fileList) {
> try { open F, $file; } catch { next; }
> try { &$closure(*F); } finally { close F; }
> return;
> }
> throw Exception "Can't open any file.",
> debug => @fileList . " tried.";
> }
It took me a while to realize that this sub is trying to find out if it can
open any of the files on its list, and if so, it performs the "closure"
operation on the first such file. Otherwise it fails.
sub AttemptClosureAfterSuccessfulCandidateFileOpen
{
my ($closure, @fileList) = @_; local (*F);
foreach my $file (@fileList) {
open F, $file; catch { next; }
&$closure(*F) always close F;
return;
}
throw Exception "Can't open any file.",
debug => @fileList . " tried.";
}
> try { ... }
> catch Exception::Foo => { ... }
> catch Exception::Bar => { ... }
> catch { ... }
> finally { ... }
{ ... } always { ... }
catch Exception::Foo => { ... }
catch Exception::Bar => { ... }
catch { ... }
> try { ... } catch $@->{message} =~ /.../ => { ... }
{ ... ; catch $_[0]->{message} =~ /.../ => { ... }}
> try { ... } catch ref $@ =~ /.../ => { ... }
> try { ... } catch grep { $_->isa("Foo") } @@ => { ... }
> try { ... } catch grep { $@->isa($_) } @list => { ... }
> try { ... } catch $@->isa("Foo") && $@->CanBar => { ... }
The above are all just demonstrating different parameters to catch; we have
little difference there for the case that list thrown consists of a single
object, just replace $@ with $_[0], and you have it.
> try { my $p = P->new; my $q = Q->new; ... }
> finally { $p and $p->Done; }
> finally { $q and $q->Done; }
my $p = P->new always $p->Done;
my $q = Q->new always $q->Done;
> try { TryToFoo; }
> catch { TryToHandle; }
> finally { TryToCleanUp; }
> catch { throw Exception "Can't cleanly Foo."; }
This example is the same as one above but with the "..." replaced with
function calls, about which I made a comment regarding the inconsistent
description of how many catch blocks can be entered in a single try
statement.
> try {
> $avoidCatches_JustUnwind = predicate();
> }
> catch $avoidCatches_JustUnwind => { throw $@ }
> catch { ... }
> finally { ... }
This example is meaningless, unless there are additional statements before
the try block's trailing "}". Because any throws within predicate will find
$avoidCatches_JustUnwind set to whatever value it had when the block was
entered.
{ $avoidCatches_JustUnwind = predicate() always { ... };
catch $avoidCatches_JustUnwind { throw @_ }
catch { ... };
}
--
Glenn
=====
There are two kinds of people, those
who finish what they start, and so
on... -- Robert Byrne
____________NetZero Free Internet Access and Email_________
Download Now http://www.netzero.net/download/index.html
Request a CDROM 1-800-333-3633
___________________________________________________________