Re: End-of-scope actions: Background.
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.
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.
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.
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.
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.
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