Re: End-of-scope actions: Background.

2001-02-20 Thread Graham Barr

On Tue, Feb 20, 2001 at 03:49:13AM +, Simon Cozens wrote:
 On Mon, Feb 12, 2001 at 01:58:35PM -0700, Tony Olekshy wrote:
  Hi, it's me again, the guy who won't shut up about exception handling.
  I'm trying,
 
 I'm catching.

And I'm thowing (up :)

Graham.




Re: End-of-scope actions: Background.

2001-02-19 Thread Simon Cozens

On Mon, Feb 12, 2001 at 01:58:35PM -0700, Tony Olekshy wrote:
 Hi, it's me again, the guy who won't shut up about exception handling.
 I'm trying,

I'm catching.

-- 
"Dogs believe they are human.  Cats believe they are God."



Re: End-of-scope actions: Background.

2001-02-14 Thread Tony Olekshy

Peter Scott wrote:

  try {
  die "foo";
  } catch {
  die "bar";
  }
 
  [...]
 
 Surely the first one catches it cleanly since it has a
 "catch-all" catch clause.

That "catch-all" clause throws.  In RFC 88 we said, in the
Definitions section,

Cleanly caught

This means the trapping and handling of an exception did not
itself raise an exception.

So the first one is caught, but it's not cleanly caught.

What's the difference?  Consider try { ... } catch { foo() }.  If
foo() throws then try's exception isn't cleanly caught, so unwinding
*is* propagated at the end of the try statement.  If foo() doesn't
throw the exception is cleanly caught, so unwinding is *not*
propagated at the end of the try statement.

Consider

$r = try { $x / $y } catch { $x / $z };
f();

If $y == 0 you want to use $x / $z for $r and then call f().

But wait, *unless* $z == 0 too, in which case you want to unwind, no?

So, we propagate after an exception if it is not "cleanly" caught.
Just catching it is not enough to terminate propagation, the
catching has itself to be "clean", otherwise there's an exception
in the catch that hasn't been caught.  There's a failure in the
failure handling.  You want to report that, not catch it.  (And if
you do want to catch it, just add clauses.)

Yours, c, Tony Olekshy



Re: End-of-scope actions: Background.

2001-02-13 Thread Tony Olekshy

Branden wrote:
 
 There's something I didn't quite understand about RFC 88:
 
 When I
 
 try {
 die "foo";
 } catch {
 die "bar";
 }
 
 I die with "bar", right? But what happens if I
 
 try {
 die "foo";
 } finally {
 die "bar";
 }
 
 I die with "foo" or "bar"? Why is this the right behaviour? Any
 sample code that shows why this should be done this way and not
 the other?

I both cases, since the "foo" exception is not cleanly caught by
either example, unwinding will be propagated at the end of the try
statement.  The code in catch and finally clauses of any outer try
clause (one "containing" the above examples, but not necessary in
the same lexical scope) will see the following:

$@[0] eq "bar" and $@[1] eq "foo" and $@ = $@[0]

with the proviso that the items in the @@ list are actually
exception objects that stringify back to the message passed to die.

In other words, RFC 88 maintains in @@ a stack of all exceptions
raised while in the process of handling and propagating unwinding,
with new exceptions unshifted to occupy $@[0] when they occur.  This
stack is only cleared when exception handling cleanly catches (that
is, a catch clause matches and completes without itself raising an
exception).

Two useful results arise from this technique.

 1) In a catch block, print join("\n", @@), "\n"; effectively
generates an exception stack traceback.  In fact, RFC 88 allows
you to say $@-show with that effect, and supports options for
including things like showing the Perl stack traceback as at the
raising of the first exception (the one in $@[-1]), showing
exeption class names, and/or showing other debug information
only to developers and log files, but not to end users.  That's
how it generates messages like this

UIM.1234: Can't add a new person to the database.
APP.2345: Can't update Company relationship.
DBM.3456: Trouble processing SQL UPDATE clause.
DBM.4567: Unable to write to Locations table.
IOM.5678: Can't open file ".../locations.ndx".
IOM.6789: File ".../locations.ndx" not found.

which I referred to in
http:[EMAIL PROTECTED]/msg05799.html

 2) In the test expression in a conditional catch clause, you can
operate on the entire @@ stack.  For example,

try { ... } catch grep { $_-isa("Foo") } @@ = { bar(); }

will call bar() only if the try block unwinds *and* any of the
exceptions involved in the unwinding are instances of a class
that inherits from Foo.

Similarly, the following two clauses

catch grep { ref $_ =~ /Alpha/ } @@ = { ... }
and
catch grep { $_ =~ /Beta/ } @@ = { ... }

match only if any exception class name matches Alpha, or any
exception's message string matches /Beta/, respectively.
You can also test other exception object properties with
tests of the form

catch grep { $_-{tag} eq "XXX.1234" } @@ = { ... }

Of course, if you're only interested in the most recent
exception, skip the grep operations in these examples and
just test $@ directly (which works because of the rule that
$@ is always equal to $@[0]).

Both of the above results are implemented in the RFC 88 Perl 5
reference implementation (modulo syntax).  There are more examples
at http://www.avrasoft.com/perl6/rfc88.htm#Examples

Yours, c, Tony Olekshy



Re: End-of-scope actions: Background.

2001-02-13 Thread Peter Scott

At 03:27 PM 2/13/01 +, Nicholas Clark wrote:
I fear I'm not adding anything apart from noise to this debate.
(partly from not having thought through the issues completely, partly by
not reading the full archives for the list from last year)

On Mon, Feb 12, 2001 at 01:58:35PM -0700, Tony Olekshy wrote:
  Or as Larry said in his ALS talk, "a completely object-oriented
  exception handling, with a simple string-like interface for those
  who do not want the power of the full OO system."  See the notes
  at http://www.avrasoft.com/perl6/rfc88.htm#CONVERSION for more
  information on how this works.

   my $f = open $file or die "can't open $file";

is troublesome. It doesn't report *why* the file can't be opened.

[snip]
errno is not flexible. *flexible* exceptions are needed
[snip]
I think that it would be nice in 5.8 to (optionally on some pragma?) make
print, close and a few others in void context croak.

It would actually make writing perl scripts easier. You'd know when your
disk became full (or you went over quota), albeit in with a messy error.
OK, script crashing with an uncaught exception isn't nice, but it's nicer
than silently losing data IMHO.

I think you'll find this addressed already in RFCs 70, 80, and 151.  At 
least, that was my intention.

http://dev.perl.org/rfc/70.html
http://dev.perl.org/rfc/80.html
http://dev.perl.org/rfc/151.html


--
Peter Scott
Pacific Systems Design Technologies




Re: End-of-scope actions: Background.

2001-02-13 Thread Peter Scott

At 10:35 AM 2/13/01 -0800, I wrote:
I think you'll find this addressed already in RFCs 70, 80, and 151.  At 
least, that was my intention.

Urp, poorly worded.  Should be, "my intention in the two RFCs out of these 
three that I wrote."  Don't want to appear to be trying to claim credit for 
RFC 70 here.

http://dev.perl.org/rfc/70.html
http://dev.perl.org/rfc/80.html
http://dev.perl.org/rfc/151.html

--
Peter Scott
Pacific Systems Design Technologies