Author: larry
Date: Wed Mar 14 11:08:52 2007
New Revision: 14346
Modified:
doc/trunk/design/syn/S06.pod
Log:
Further refinement of caller semantics to dwim in displaced closure calls.
Modified: doc/trunk/design/syn/S06.pod
==============================================================================
--- doc/trunk/design/syn/S06.pod (original)
+++ doc/trunk/design/syn/S06.pod Wed Mar 14 11:08:52 2007
@@ -1735,6 +1735,11 @@
$ctx = context(1,0,1,1); # my context's context's context's context
$ctx = context($i); # $i'th context
+Note also that negative numbers are allowed as long as you stay within
+the existing context stack:
+
+ $ctx = context(4,-1); # my context's context's context's context
+
Repeating any smartmatch just matches the same context again unless you
intersperse a 1 to skip the current level:
@@ -1764,12 +1769,15 @@
$ctx = context;
$ctx = context.context.context.context; # same
-The C<caller> function is special-cased to pay attention only to
-the current C<Routine> scope. It is defined as navigating to the
-innermost scope matching C<&?ROUTINE> (which may be a no-op when
-immediately inside a routine) and then going out one context from that:
-
- &caller ::= &context.assuming(&?ROUTINE,1);
+The C<caller> function is special-cased to go outward just far enough
+to escape from the current routine scope, after first ignoring any
+inner blocks that are embedded, or are otherwise pretending to be "inline":
+
+ &caller ::= &context.assuming({ !.inline }, 1);
+
+Note that this is usually the same as C<context(&?ROUTINE,1)>,
+but not always. A call to a returned closure might not even have
+C<&?ROUTINE> in its dynamic scope anymore, but it still has a caller.
So to find where the current routine was called you can say:
@@ -1781,10 +1789,12 @@
say " file ", CALLER::<$?FILE>,
" line ", CALLER::<$?LINE>;
-Note that one context out is I<not> guaranteed to be a C<Routine>
-context. You must say C<caller(Routine)> to get to the next-most-inner
-routine, which is equivalent to C<context(&?ROUTINE,1,Routine)>.
-But C<caller(Routine).line> is not necessarily going to give you the
+Additional arguments to C<caller> are treated as navigational from the
+calling context. One context out from your current routine is I<not>
+guaranteed to be a C<Routine> context. You must say C<caller(Routine)>
+to get to the next-most-inner routine.
+
+Note that C<caller(Routine).line> is not necessarily going to give you the
line number that your current routine was called from; you're rather
likely to get the line number of the topmost block that is executing
within that outer routine, where that block contains the call to
@@ -1793,18 +1803,27 @@
For either C<context> or C<caller>,
the returned context object supports at least the following methods:
- .want
.context
.caller
+ .leave
+ .want
+ .inline
.my
.file
.line
.subname
-The C<.caller> method is subtly different from the C<caller>
-function. Instead of looking up the current lexically scoped caller
-by C<.context(&?ROUTINE,1)>, it just looks up the next matching dynamic
-caller using C<.context(Routine,1)>.
+The C<.context> and C<.caller> methods work the same as the functions
+except that they are relative to the context supplied as invocant.
+The C<.leave> method can force an immediate return from the
+specified context. The C<.want> method returns known smart-matchable
+characteristics of the specified context.
+
+The C<.inline> method says whether this block was entered implicitly
+by some surrounding control structure. Any time you invoke a block or
+routine explicitly with C<.()> this is false. However, it is defined
+to be true for any block entered using dispatcher-level primitives
+such as C<.callwith>, C<.callsame>, C<.nextwith>, or C<.nextsame>.
The C<.my> method provides access to the lexical namespace in effect at
the given dynamic context's current position. It may be used to look