Skip to content

Commit

Permalink
History as written by the winners:
Browse files Browse the repository at this point in the history
    The Long-Promised Grand Unification of + and * Twigils
History as written by the losers:
    The Genocidal Slaughter of Innocent + Twigils

(anyway, rouso++ for reminding me again)

Also:
    cleanup of %*ENV semantics, wrt run()
    removal of postfix:<::> from S02
    clarification of %*OPTS scoping


git-svn-id: http://svn.pugscode.org/pugs@25297 c213334d-75ef-0310-aa23-eaa082d1ae64
  • Loading branch information
lwall committed Feb 11, 2009
1 parent a7fb88d commit 27c19bb
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 46 deletions.
83 changes: 51 additions & 32 deletions S02-bits.pod
Original file line number Diff line number Diff line change
Expand Up @@ -1390,8 +1390,7 @@ is subject to:
$.foo object attribute accessor
$^foo self-declared formal positional parameter
$:foo self-declared formal named parameter
$*foo global variable
$+foo contextual variable
$*foo contextualizable global variable
$?foo compiler hint variable
$=foo pod variable
$<foo> match variable, short for $/{'foo'}
Expand Down Expand Up @@ -1925,74 +1924,94 @@ by reference, to add symbols to a lexical scope that is done compiling.
The C<CALLER> package refers to the lexical scope of the (dynamically
scoped) caller. The caller's lexical scope is allowed to hide any
variable except C<$_> from you. In fact, that's the default, and a
user-defined variable from you. In fact, that's the default, and a
lexical variable must have the trait "C<is context>" to be
visible via C<CALLER>. (C<$_>, C<$!> and C<$/> are always
contextual.) If the variable is not visible in the caller, it returns
failure. Variables whose names are visible at the point of the call but that
come from outside that lexical scope are controlled by the scope
in which they were originally declared.
Hence the visibility of C<< CALLER::<$+foo> >> is determined where
C<$+foo> is actually declared, not by the caller's scope. Likewise
C<< CALLER::CALLER::<$x> >> depends only on the declaration of C<$x>
visible in your caller's caller.
in which they were originally declared as contextual.
Hence the visibility of C<< CALLER::<$*foo> >> is determined where
C<$*foo> is actually declared, not by the caller's scope (unless that's where
it happens to be declared). Likewise C<< CALLER::CALLER::<$x> >>
depends only on the declaration of C<$x> visible in your caller's caller.

Any lexical declared with the C<is context> trait is by default
considered readonly outside the current lexical scope. You may
add a trait argument of C<< <rw> >> to allow called routines to
modify your value. C<$_>, C<$!>, and C<$/> are C<< context<rw> >>
by default. In any event, your lexical scope can always access the
variable as if it were an ordinary C<my>; the restriction on writing
applies only to called subroutines.
by default. In any event, the declaring scope can always access the
variable as if it were an ordinary variable; the restriction on writing
applies only to access via the C<*> twigil.

=item *
The C<CONTEXT> 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 context's lexical scope.
(Use of C<$+FOO> is equivalent to C<< CONTEXT::<$FOO> >> or C<< $CONTEXT::FOO >>.)
(Use of C<$*FOO> is equivalent to C<< CONTEXT::<$FOO> >> or C<< $CONTEXT::FOO >>.)
If after scanning all the lexical scopes of each dynamic scope,
there is no variable of that name, it looks in the C<*> package.
If there is no variable in the C<*> package and the variable is
a scalar, it then looks in C<%*ENV> for the identifier of the variable,
there is no variable of that name, it looks in the C<GLOBAL> package followed
by the C<PROCESS> package.
If there is no such package variable,
it then looks in C<CONTEXT::<%ENV> for the identifier of the variable,
which, if not overridden in a dynamic scope, finds C<< PROCESS::<%ENV> >>,
that is, in the environment variables passed to program. If the
value is not found there, it returns failure. Unlike C<CALLER>,
C<CONTEXT> will see a contextual variable that is declared in
value is not found there, it returns failure. If the variable is
of the form C<$*FOO>, the complete environment value is returned. If it
is of the form C<@*FOO> the string will be split either on colons or
semicolons as appropriate to the current operating system. Usage of
the C<%*FOO> form is currently undefined.

Unlike C<CALLER>, C<CONTEXT> will see a contextual variable that is declared in
the current scope, however it will not be writeable via C<CONTEXT> unless
declared "C<< is context<rw> >>", even if the variable itself is
modifiable in that scope. (If it is, you should just use the bare
variable itself to modify it.) Note that C<$+_> will always see
variable itself to modify it.) Note that C<$*_> will always see
the C<$_> in the current scope, not the caller's scope. You may
use C<< CALLER::<$+foo> >> to bypass a contextual definition of C<$foo>
use C<< CALLER::<$*foo> >> to bypass a contextual definition of C<$foo>
in your current context, such as to initialize it with the outer
contextual value:

my $foo is context = CALLER::<$+foo>;
my $foo is context = CALLER::<$*foo>;

The C<temp> maybe used on a contextual variable to perform a similar operation:

temp $*foo;

The main difference is that by default it initializes the new
C<$*foo> with its previous value, rather than the caller's value.
The temporized contextual variable takes its read/write policy from
the previous C<$*foo> container.

The C<CONTEXT> package is only for internal overriding of contextual
The C<CONTEXT> package is primarily for internal overriding of contextual
information, modelled on how environmental variables work among
processes. Despite the fact that the C<CONTEXT> package reflects the
current process's environment variables, at least where those are not
hidden by lower-level declarations, the C<CONTEXT> package should not
be considered isomorphic to the current set of environment variables.
Subprocesses are passed only the global C<%*ENV> values. They do
not see any lexical variables or their values, unless you copy those
values into C<%*ENV> to change what subprocesses see:

temp %*ENV{LANG} = $+LANG; # may be modified by parent
current process's environment variables individually where those are not
hidden by lower-level declarations, the actual set of environment variables
that will be passed to subprocesses is taken from the C<%*ENV> variable.
Hence you must override that variable itself to influence what is
passed to subprocesses. That is,

temp $*LANG = "ja_JP.utf8"; # WRONG
run "greet";

does not set the LANG environment variable for the greet program. Instead
you should make a private copy of the environment and modify that:

temp %*ENV;
%*ENV<LANG> = "ja_JP.utf8"; # ok
run "greet";

=item *
There is no longer any special package hash such as C<%Foo::>. Just
subscript the package object itself as a hash object, the key of which
is the variable name, including any sigil. The package object can
be derived from a type name by use of the C<::> postfix operator:
be derived from a type name by use of the C<::> postfix:

MyType::<$foo>
MyType.::.{'$foo'} # same thing with dots
MyType\ ::\ {'$foo'} # same thing with unspaces

(Directly subscripting the type with either square brackets or curlies
is reserved for various generic type-theoretic operations. In most other
Expand Down
19 changes: 11 additions & 8 deletions S19-commandline.pod
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Jerry Gay <jerry.gay@rakudoconsulting.com>

Maintainer: Jerry Gay <jerry.gay@rakudoconsulting.com>
Date: 12 Dec 2008
Last Modified: 8 Feb 2009
Version: 23
Last Modified: 11 Feb 2009
Version: 24

This is a draft document. This document describes the command line interface.
It has changed extensively from previous versions of Perl in order to increase
Expand Down Expand Up @@ -303,30 +303,33 @@ like a closing HTML tag.
=back

These options are made available in context variables matching their name,
and are invisible to C<MAIN()> except as C<< %+OPTS<name> >>. For example:
and are invisible to C<MAIN()> except as C<< %*OPTS<name> >>. For example:

++PARSER --setting=Perl6-autoloop-no-print ++/PARSER

is available inside your script as C<< %+OPTS<PARSER> >>, and contains
is available inside your script as C<< %*OPTS<PARSER> >>, and contains
C<--setting=Perl6-autoloop-no-print>. Since eager matching is used, if you
need to pass something like:

++foo -bar ++foo baz ++/foo ++/foo

you'll end up with

%+OPTS<foo> = '-bar ++foo baz';
%*OPTS<foo> = '-bar ++foo baz';

which is probably not what you wanted. Instead, add extra C<+> characters

+++foo -bar ++foo baz ++/foo +++/foo

which will give you

%+OPTS<foo> = '-bar ++foo baz ++/foo';
%*OPTS<foo> = '-bar ++foo baz ++/foo';

allowing you to properly nest delimited options.

The actual storage location of C<%*OPTS> may be either in C<< PROCESS::<%OPTS> >>
or C<< GLOBAL::<%OPTS> >>, depending on how the process sets up its interpreters.


Values are parsed with the following rules:

Expand Down Expand Up @@ -403,7 +406,7 @@ Check syntax, then exit. Desugars to C<-e 'CHECK{ compiles_ok(); exit; }'>.
=item --doc

Lookup Perl documentation in Pod format. Desugars to
C<-e 'CHECK{ compiles_ok(); dump_perldoc(); }'>. C<$+ARGS> contains the
C<-e 'CHECK{ compiles_ok(); dump_perldoc(); }'>. C<$*ARGS> contains the
arguments passed to C<perl6>, and is available at C<CHECK> time, so
C<dump_perldoc()> can respond to command-line options.

Expand Down Expand Up @@ -510,7 +513,7 @@ Desugars to C<--PARSER --Perl6-extract-from-text --/PARSER>.

Metasyntactic options are a subset of delimited options used to pass arguments
to an underlying component of Perl. Perl itself does not parse these options,
but makes them available to run-time components via the C<%+META-ARGS> context
but makes them available to run-time components via the C<%*META-ARGS> context
variable.

Standard in Perl 6 are three underlying components, C<CMD>, C<PARSER>,
Expand Down
12 changes: 6 additions & 6 deletions S29-functions.pod
Original file line number Diff line number Diff line change
Expand Up @@ -2058,13 +2058,13 @@ signal at all, and is used to determine if processes are still running:

=item run

our Proc::Status multi run ( ; Str $command )
our Proc::Status multi run ( ; Str $path, *@args )
our Proc::Status multi run ( Str @path_and_args )
our Proc::Status multi run ( ; Str $command, :%env = %*ENV )
our Proc::Status multi run ( ; Str $path, *@args, :%env = %*ENV )
our Proc::Status multi run ( Str @path_and_args, :%env = %*ENV )

our Proc multi run ( ; Str $command, Bool :$bg! )
our Proc multi run ( ; Str $path, Bool :$bg!, *@args )
our Proc multi run ( Str @path_and_args, Bool :$bg! )
our Proc multi run ( ; Str $command, Bool :$bg!, :%env = %*ENV )
our Proc multi run ( ; Str $path, Bool :$bg!, *@args, :%env = %*ENV )
our Proc multi run ( Str @path_and_args, Bool :$bg!, :%env = %*ENV )

C<run> executes an external program, and returns control to the caller
once the program has exited.
Expand Down

0 comments on commit 27c19bb

Please sign in to comment.