I propose that we change $! (formerly global) and $/ (formerly
implicitly lexical) to being env variables.  Here is the IRC
conversation where Audrey convinced me:
http://colabti.de/irclogger/irclogger_log/perl6?date=2006-01-01,Sun&sel=1213#l1893

Let me explain env variables, because my misunderstanding of those is
what caused me to oppose the idea.  An env variable can be thought of
as an implicit parameter to a function.  A function retrieves said
implicit parameters using the + twigil.  So this code:

    sub bar() {
        say $+foo;
    }
    sub baz() {
        env $foo = 42;
        bar();
    }

Could be rewritten:

    sub bar($foo) {
        say $foo;
    }
    sub baz() {
        bar(foo => 42);
    }

The + twigil is *necessary*, so it's different from a temporized
global.  This code:

    sub bar() {
        say $foo;
    }
    sub baz() {
        env $foo = 42;
        bar();
    }

Dies with "$foo undeclared at line 2".

Env variables are implicitly passed up through any number of call
frames.  So baz() could declare an env $foo, and bar() could call
bar(), which calls quux(), which calls foo(), and foo() could ask for
$+foo.

The decision to make $! non-global is obvious:

    sub trace($msg) {
        try { say $msg }
    }
    try {
        maybe_dies();
        CATCH {
            trace("got here");
            when X::Foo {...}  # uh oh, is referring to trace()'s $!
        }
    }

Making $! lexical or environmental solves that problem.  Keeping it
environmental allows you to write your own catch() handlers.

$/ was formerly lexical, and making it environmental, first of all,
allows substitutions to be regular functions:

    $foo.subst(rx| /(.*?)/ |, { "<it>$1</it>" })

Since .subst could choose bind $/ on behalf of its caller.

It is also aesthetically appealing to have all (three) punctuation
variables being environmental.

Here's a patch to S02:

Luke

Index: S02.pod
===================================================================
--- S02.pod     (revision 7048)
+++ S02.pod     (working copy)
@@ -467,9 +467,7 @@
 Many of the special variables of Perl 5 are going away.  Those that
 apply to some object such as a filehandle will instead be attributes
 of the appropriate object.  Those that are truly global will have
-global alphabetic names, such as C<$*PID> or C<@*ARGS>.  Certain of
-these global values may retain punctuational shortcuts, such as C<$!>
-for C<$*ERROR>.
+global alphabetic names, such as C<$*PID> or C<@*ARGS>.

 =item *

@@ -604,9 +602,10 @@
 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
-lexical variable must be declared using "C<env>" rather than C<my> to
be visible via C<CALLER>.
-(C<$_> is always environmental. [Conjectural: so are C<$!> and C<$/>.])
-If the variable is not visible in the caller, it returns failure.
+lexical variable must be declared using "C<env>" rather than C<my> to be
+visible via C<CALLER>.  (C<$_>, C<$!> and C<$/> are always
+environmental.) If the variable is not visible in the caller, it returns
+failure.

 An explicit C<env> declaration is implicitly readonly.  You may add
 C<is rw> to allow subroutines from modifying your value.  C<$_> is

Reply via email to