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

Reply via email to