Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[specs] s/CONTEXT/DYNAMIC/ to avoid confusion of concepts
git-svn-id: http://svn.pugscode.org/pugs@29112 c213334d-75ef-0310-aa23-eaa082d1ae64
  • Loading branch information
lwall committed Nov 17, 2009
1 parent 889b513 commit 7b198c7
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 54 deletions.
10 changes: 5 additions & 5 deletions S02-bits.pod
Expand Up @@ -14,7 +14,7 @@ Synopsis 2: Bits and Pieces
Created: 10 Aug 2004

Last Modified: 17 Nov 2009
Version: 188
Version: 189

This document summarizes Apocalypse 2, which covers small-scale
lexical items and typological issues. (These Synopses also contain
Expand Down Expand Up @@ -2030,7 +2030,7 @@ The following pseudo-package names are reserved at the front of a name:
PROCESS # Process-related globals (superglobals)
COMPILING # Lexical symbols in the scope being compiled
CALLER # Contextual symbols in the immediate caller's lexical scope
CONTEXT # Contextual symbols in my or any caller's lexical scope
DYNAMIC # Contextual symbols in my or any caller's lexical scope

The following relative names are also reserved but may be used
anywhere in a name:
Expand Down Expand Up @@ -2283,18 +2283,18 @@ need not be locked.)

=item *

The C<CONTEXT> pseudo-package is just like C<CALLER> except that
The C<DYNAMIC> pseudo-package is just like C<CALLER> except that
it starts in the current dynamic scope and from there scans outward
through all dynamic scopes until it finds a contextual variable of that
name in that dynamic context's associated lexical pad. (This search
is implied for variables with the C<*> twigil; hence C<$*FOO> is
equivalent to C<< CONTEXT::<$*FOO> >>.) If, after scanning outward
equivalent to C<< DYNAMIC::<$*FOO> >>.) If, after scanning outward
through all those dynamic scopes, there is no variable of that name
in any immediately associated lexical pad, it strips the C<*> twigil
out of the name and looks in the C<GLOBAL> package followed by the
C<PROCESS> package. If the value is not found, it returns failure.

Unlike C<CALLER>, C<CONTEXT> will see a contextual variable that is
Unlike C<CALLER>, C<DYNAMIC> will see a contextual variable that is
declared in the current scope, since it starts search 0 scopes up the
stack rather than 1. You may, however, use C<< CALLER::<$*foo> >>
to bypass a contextual definition of C<$*foo> in your current context,
Expand Down
8 changes: 4 additions & 4 deletions S04-control.pod
Expand Up @@ -13,8 +13,8 @@ Synopsis 4: Blocks and Statements

Created: 19 Aug 2004

Last Modified: 12 Nov 2009
Version: 87
Last Modified: 17 Nov 2009
Version: 88

This document summarizes Apocalypse 4, which covers the block and
statement syntax of Perl.
Expand Down Expand Up @@ -634,8 +634,8 @@ therefore loop control statements.
Although a bare block occuring as a single statement is no longer
a do-once loop, it still executes immediately as in Perl 5, as if it
were immediately dereferenced with a C<.()> postfix, so within such a
block C<CONTEXT::> refers to the scope surrounding the block. But unlike
an explicit call, C<CALLER::> doesn't count it as a routine boundary.
block C<CALLER::> refers to the dynamic scope associated
with the lexical scope surrounding the block.

If you wish to return a closure from a function, you must use an
explicit prefix such as C<return> or C<sub> or C<< -> >>.
Expand Down
80 changes: 40 additions & 40 deletions S06-routines.pod
Expand Up @@ -2140,9 +2140,9 @@ In any event, such a function is called only once at the time the
C<Capture> object is generated, not when it is later bound (which
could happen more than once).

=head2 The C<context> and C<caller> functions
=head2 The C<dynamic> and C<caller> functions

The C<context> function takes a list of matchers and interprets them
The C<dynamic> function takes a list of matchers and interprets them
as a navigation path from the current context to a location in the
dynamic scope, either the current context itself or some context
from which the current context was called. It returns an object
Expand All @@ -2153,79 +2153,79 @@ context matching the argument as a smartmatch.

The current context is accessed with a null argument list.

say " file ", context().file,
" line ", context().line;
say " file ", dynamic().file,
" line ", dynamic().line;

which is equivalent to:

say " file ", CONTEXT::<$?FILE>,
" line ", CONTEXT::<$?LINE>;
say " file ", DYNAMIC::<$?FILE>,
" line ", DYNAMIC::<$?LINE>;

The immediate caller of this context is accessed by skipping one level:

say " file ", context(1).file,
" line ", context(1).line;
say " file ", dynamic(1).file,
" line ", dynamic(1).line;

You might think that that must be the current function's caller,
but that's not necessarily so. This might return an outer block in
our own routine, or even some function elsewhere that implements a
control operator on behalf of our block. To get outside your current
routine, see C<caller> below.

The C<context> function may be given arguments
The C<dynamic> function may be given arguments
telling it which higher scope to look for. Each argument is processed
in order, left to right. Note that C<Any> and C<0> are no-ops:

$ctx = context(); # currently running context for &?BLOCK
$ctx = context(Any); # currently running context for &?BLOCK
$ctx = context(Any,Any); # currently running context for &?BLOCK
$ctx = context(1); # my context's context
$ctx = context(2); # my context's context's context
$ctx = context(3); # my context's context's context's context
$ctx = context(1,0,1,1); # my context's context's context's context
$ctx = context($i); # $i'th context
$ctx = dynamic(); # currently running context for &?BLOCK
$ctx = dynamic(Any); # currently running context for &?BLOCK
$ctx = dynamic(Any,Any); # currently running context for &?BLOCK
$ctx = dynamic(1); # my context's context
$ctx = dynamic(2); # my context's context's context
$ctx = dynamic(3); # my context's context's context's context
$ctx = dynamic(1,0,1,1); # my context's context's context's context
$ctx = dynamic($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
$ctx = dynamic(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:

$ctx = context(Method); # nearest context that is method
$ctx = context(Method,Method); # nearest context that is method
$ctx = context(Method,1,Method); # 2nd nearest method context
$ctx = context(Method,1,Method,1) # caller of that 2nd nearest method
$ctx = context(1,Block); # nearest outer context that is block
$ctx = context(Sub,1,Sub,1,Sub); # 3rd nearest sub context
$ctx = context({ .labels.any eq 'Foo' }); # nearest context labeled 'Foo'
$ctx = dynamic(Method); # nearest context that is method
$ctx = dynamic(Method,Method); # nearest context that is method
$ctx = dynamic(Method,1,Method); # 2nd nearest method context
$ctx = dynamic(Method,1,Method,1) # caller of that 2nd nearest method
$ctx = dynamic(1,Block); # nearest outer context that is block
$ctx = dynamic(Sub,1,Sub,1,Sub); # 3rd nearest sub context
$ctx = dynamic({ .labels.any eq 'Foo' }); # nearest context labeled 'Foo'

Note that this last potentially differs from the answer returned by

Foo.context
Foo.dynamic

which returns the context of the innermost C<Foo> block in the lexical scope
rather than the dynamic scope. A context also responds to the C<.context>
rather than the dynamic scope. A context also responds to the C<.dynamic>
method, so a given context may be used as the basis for further navigation:

$ctx = context(Method,1,Method);
$ctx = context(Method).context(1).context(Method); # same
$ctx = dynamic(Method,1,Method);
$ctx = dynamic(Method).dynamic(1).dynamic(Method); # same

You must supply args to get anywhere else, since C<.context> is
You must supply args to get anywhere else, since C<.dynamic> is
the identity operator when called on something that is already
a C<Context>:

$ctx = context;
$ctx = context.context.context.context; # same
$ctx = dynamic;
$ctx = dynamic.dynamic.dynamic.dynamic; # same

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);
&caller ::= &dynamic.assuming({ !.inline }, 1);

Note that this is usually the same as C<context(&?ROUTINE,1)>,
Note that this is usually the same as C<dynamic(&?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.

Expand All @@ -2250,10 +2250,10 @@ likely to get the line number of the topmost block that is executing
within that outer routine, where that block contains the call to
your routine.

For either C<context> or C<caller>,
For either C<dynamic> or C<caller>,
the returned context object supports at least the following methods:

.context
.dynamic
.caller
.leave
.inline
Expand All @@ -2263,7 +2263,7 @@ the returned context object supports at least the following methods:
.my
.hints

The C<.context> and C<.caller> methods work the same as the functions
The C<.dynamic> 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.
Expand All @@ -2277,7 +2277,7 @@ 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
up ordinary lexical variables in that lexical scope. It must not be
used to change any lexical variable that is not marked as C<< context<rw> >>.
used to change any lexical variable that is marked as readonly.

The C<.hints> method gives access to a snapshot of compiler symbols in
effect at the point of the call when the call was originally compiled.
Expand Down Expand Up @@ -2901,9 +2901,9 @@ was called, provided that variable carries the "C<context>"
trait. (All variables with a C<*> twigil are automatically marked with the trait.
Likewise certain implicit lexicals (C<$_>, C<$/>, and C<$!>) are so marked.)

C<< CONTEXT::<$varname> >> specifies the C<$varname> visible in the
C<< DYNAMIC::<$varname> >> specifies the C<$varname> visible in the
innermost dynamic scope that declares the variable with the "C<is context>"
trait.
trait or with a name that has the C<*> twigil.

C<< MY::<$varname> >> specifies the lexical C<$varname> declared in the current
lexical scope.
Expand Down
16 changes: 11 additions & 5 deletions S11-modules.pod
Expand Up @@ -13,8 +13,8 @@ Synopsis 11: Modules

Created: 27 Oct 2004

Last Modified: 30 Jun 2009
Version: 30
Last Modified: 17 Nov 2009
Version: 31

=head1 Overview

Expand Down Expand Up @@ -126,14 +126,16 @@ C<EXPORT> method with the class itself as the invocant.
=head1 Compile-time Importation
X<use>

[Note: the :MY forms are being rethought currently.]

Importing via C<use> binds into the current lexical scope by default
(rather than the current package, as in Perl 5).

use Sense <common @horse>;

You can be explicit about the desired namespace:

use Sense :MY<common> :OUR<@horse> :CONTEXT<$sensitive>;
use Sense :MY<common> :OUR<@horse>;

That's pretty much equivalent to:

Expand Down Expand Up @@ -312,13 +314,17 @@ to the package scope instead:
You may also import symbols from the various pseudo-packages listed in S02.
They behave as if all their symbols are in the C<:ALL> export list:

import CONTEXT <$IN $OUT $ERR>;
import PROCESS <$IN $OUT $ERR>;
import CALLER <$x $y>;

# Same as:
# my ($IN, $OUT, $ERR) ::= ($*IN, $*OUT, $*ERR)
# my ($IN, $OUT, $ERR) := PROCESS::<$IN $OUT $ERR>
# my ($x, $y) := ($CALLER::x, $CALLER::y)

[Conjecture: this section may go away, since the aliasing forms
are not all that terrible, and it's not clear that we want the
overhead of emulating export lists.]

=head1 Versioning

When at the top of a file you say something like
Expand Down

0 comments on commit 7b198c7

Please sign in to comment.