Author: lwall
Date: 2010-07-10 00:55:41 +0200 (Sat, 10 Jul 2010)
New Revision: 31609

Modified:
   docs/Perl6/Spec/S04-control.pod
   docs/Perl6/Spec/S06-routines.pod
Log:
[S04,6] more refinement of how scoping works under DBC
note that all phasers in methods to have access to self via closure


Modified: docs/Perl6/Spec/S04-control.pod
===================================================================
--- docs/Perl6/Spec/S04-control.pod     2010-07-09 22:39:12 UTC (rev 31608)
+++ docs/Perl6/Spec/S04-control.pod     2010-07-09 22:55:41 UTC (rev 31609)
@@ -14,7 +14,7 @@
     Created: 19 Aug 2004
 
     Last Modified: 9 Jul 2010
-    Version: 99
+    Version: 100
 
 This document summarizes Apocalypse 4, which covers the block and
 statement syntax of Perl.
@@ -1379,17 +1379,31 @@
 before C<BEGIN>, C<CHECK>, or C<INIT>, since those are done at compile or
 process initialization time).  Much like C<BUILD> and C<DESTROY> are implicitly
 called in the correct order by C<BUILDALL> and C<DESTROYALL>, the 
C<PRE>/C<POST>
-calls are via an implicit C<ENFORCEALL> method that runs
+calls are via an implicit C<CALL-VIA-DBC> method that runs
 outside the actual call to the method in question.  Class-level C<PRE>/C<POST>
 submethods are notionally outside of the method-level C<PRE>/C<POST> blocks.
-At each submethod level, C<ENFORCEALL> calls (in the normal course of things):
+In the normal course of things, C<CALL-VIA-DBC> follows these steps:
 
-    1. class's C<PRE> submethod
-    2. method's C<PRE> phaser
-    3. method call
-    4. method's C<POST> phaser
-    5. class's C<POST> submethod
+    1. create an empty stack for scheduling postcalls.
+    2. call all the appropriate per-class C<PRE> submethods,
+        pushing any corresponding C<POST> onto the postcall stack.
+    3. call all the appropriate per-method C<PRE> phasers,
+        pushing any corresponding C<POST> onto the postcall stack.
+    4. enforce DBC logic of C<PRE> calls
+    5. call the method call itself, capturing return/unwind status.
+    6. pop and call every C<POST> on the postcall stack.
+    7. enforce DBC logic of C<POST> calls
+    8. continue with the return or unwind.
 
+Note that in steps 2 and 3, the C<POST> block can be defined in
+one of two ways.  Either the corresponding C<POST> is defined as a
+separate declaration (submethod for 2, phaser for 3), in which case
+C<PRE> and C<POST> share no lexical scope.  Alternately, any C<PRE>
+(either submethod or phaser) may define its corresponding C<POST>
+as an embedded phaser block that closes over the lexical scope of
+the C<PRE>.  In either case, the code is pushed onto the postphaser
+stack to be run at the appropriate moment.
+
 If exit phasers are running as a result of a stack unwind initiated
 by an exception, C<$!> contains the exception that caused it, though
 it will be marked as handled by then.  In any case, the information
@@ -1416,15 +1430,22 @@
 world in raw form, so that the phaser doesn't accidentally impose
 context prematurely.)
 
-The topic of the outer block of a phaser is still available as C<< OUTER::<$_> 
>>.
+The topic of the block outside a phaser is still available as C<< OUTER::<$_> 
>>.
 Whether the return value is modifiable may be a policy of the phaser
 in question.  In particular, the return value should not be modified
 within a C<POST> phaser, but a C<LEAVE> phaser could be more liberal.
 
-Class-level C<PRE> and C<POST> submethods are not in the lexical
-scope of a method, and are not run in the dynamic scope of the method,
-so cannot see the method's C<$_> at all.
+Class-level C<PRE> and C<POST> submethods are not in the lexical scope
+of a method (and are not run in the dynamic scope of the method),
+so they cannot see the method's C<$_> at all.  As methods, they
+do have access to the current C<self>, of course.  And the C<POST>
+submethod gets the return value as the topic, just as exit phasers do.
 
+Any phaser defined in the lexical scope of a method is a closure that
+closes over C<self> as well as normal lexicals.  (Or equivalently,
+an implementation may simply turn all such phasers into submethods
+whose curried invocant is the current object.)
+
 =head1 Statement parsing
 
 In this statement:

Modified: docs/Perl6/Spec/S06-routines.pod
===================================================================
--- docs/Perl6/Spec/S06-routines.pod    2010-07-09 22:39:12 UTC (rev 31608)
+++ docs/Perl6/Spec/S06-routines.pod    2010-07-09 22:55:41 UTC (rev 31609)
@@ -17,7 +17,7 @@
     Created: 21 Mar 2003
 
     Last Modified: 9 Jul 2010
-    Version: 137
+    Version: 138
 
 This document summarizes Apocalypse 6, which covers subroutines and the
 new type system.
@@ -2093,7 +2093,8 @@
 or C<ENTER> block are automatically hoisted outward to be called at the
 same time as other C<POST> phasers.  This conveniently gives "circum"
 semantics by virtue of wrapping the post lexical scope within the pre
-lexical scope.
+lexical scope.  That is, the C<POST> closes over its outer scope, even
+if that scope is gone by the time the C<POST> is run.
 
     method push ($new_item) {
         ENTER {
@@ -2113,13 +2114,20 @@
         return pop @.items;
     }
 
-[Conjecture: class and module invariants can similarly be supplied
-by embedding C<POST>/C<post> declarations in a C<FOREIGN> block that
-only runs when any routine of this module is called from "outside"
-the current module or type, however that's defined.  The C<FOREIGN> block
-itself could perhaps refine the concept of what is foreign, much like
-an exception handler.]
+Note that C<self> is available in phasers defined within methods.
 
+Class invariants are declared with C<PRE>/C<POST> submethods instead of 
phasers.
+
+Module invariants are declared with C<PRE>/C<POST> subs or protos.
+
+[Conjecture: class and module invariants can applied more selectively
+by marking C<PRE>/C<POST> declarations with a C<selective> trait that
+stops it from running on internal calls (which might allow temporary
+violations of invariants), but enforces the invariants when any routine
+of this module is called from "outside" the current module or type,
+however that's defined.  There could be arguments to this trait that
+could refine the concept of what is foreign.]
+
 =item C<ENTER>/C<LEAVE>/C<KEEP>/C<UNDO>/etc.
 
 These phasers supply code that is to be conditionally executed before or

Reply via email to