Author: autrijus
Date: Sat Apr 1 10:35:35 2006
New Revision: 8522
Modified:
doc/trunk/design/syn/S04.pod
Log:
* S04: Specify "fail" semantics in detail, and the relationship
to the environmental $! variable. Handling and propagation
of "unthrown exceptions" clarified.
Modified: doc/trunk/design/syn/S04.pod
==============================================================================
--- doc/trunk/design/syn/S04.pod (original)
+++ doc/trunk/design/syn/S04.pod Sat Apr 1 10:35:35 2006
@@ -12,9 +12,9 @@
Maintainer: Larry Wall <[EMAIL PROTECTED]>
Date: 19 Aug 2004
- Last Modified: 28 Mar 2006
+ Last Modified: 1 Apr 2006
Number: 4
- Version: 11
+ Version: 12
This document summarizes Apocalypse 4, which covers the block and
statement syntax of Perl.
@@ -464,38 +464,34 @@
=head1 Exceptions
As in Perl 5, many built-in functions simply return undef when you ask
-for a value out of range, or the function fails somehow. Unlike in
-Perl 5, these may be "interesting" values of undef that contain
-information about the error. If you try to use an undefined value,
-that information can then be conveyed to the user. In essence, undef
-can be an unthrown exception object that just happens to return 0 when
-you ask it whether it's defined or it's true. Since C<$!> contains the
-current error code, saying C<die $!> will turn an unthrown exception
-into a thrown exception. (A bare C<die> does the same.)
+for a value out of range, or the function fails somehow. Perl 6 has
+C<Failure> objects, which refers to an unthrown C<Exception> object in
+C<$!> and knows whether it has been handled or not.
+
+If you test a C<Failure> for C<.id>, C<.defined> or C<.true>, it causes
+C<$!> to mark the exception as I<handled>, and acts as a harmless C<Undef>
+value thereafter. Any other use of the C<Failure> will throw its associated
+exception immediately.
+
+Because the C<env> variable C<$!> contains all exceptions collected in the
+current lexical scope, saying C<die $!> will throw all exceptions,
+whether they were handled or not. A bare C<die>/C<fail> takes C<$!> as the
+default argument.
+
+At scope exit, C<$!> discards all handled exceptions from itself, then performs
+a GC check for all remaining (unhandled) exceptions. If all of them are still
+alive (e.g. by becoming part of the return value), then they are appended to
+C<< CALLER::<$!> >>. Otherwise, it calls C<die> to throw those exceptions
+as a single new exception, which may then be caught with a C<CATCH> block in
+the current (or caller's) scope.
You can cause built-ins to automatically throw exceptions on failure using
use fatal;
-The C<fail> function responds to the caller's "use fatal" state. It
+The C<fail> function responds to the caller's C<use fatal> state. It
either returns an unthrown exception, or throws the exception.
-If an exception is raised while C<$!> already contains an exception
-that is active and "unhandled", no information is discarded. The old
-exception is pushed onto the exception stack within the new exception,
-which is then bound to C<$!> and, hopefully, propagated. The default
-printout for the new exception should include the old exception
-information so that the user can trace back to the original error.
-(Likewise, rethrown exceptions add information about how the exception
-is propagated.) The exception stack within C<$!> is available as
-C<$![]>.
-
-Exception objects are born "unhandled". The C<$!> object keeps track of
-whether it's currently "handled" or "unhandled". The exception in C<$!> still
-exists after it has been caught, but catching it marks it as handled
-if any of the cases in the switch matched. Handled exceptions don't
-require their information to be preserved if another exception occurs.
-
=head1 Closure traits
A C<CATCH> block is just a trait of the closure containing it. Other