From: Allison Randal <[EMAIL PROTECTED]>
   Date: Wed, 22 Nov 2006 20:37:26 -0800

   Ben Morrow wrote:
   > 
   > ...but that's just a braino on Matt's part, and his point still stands
   > for the code
   > 
   >     package Test;
   >     
   >     sub apply {
   >         my $func = shift;
   >         $func->(shift) while @_;
   >     }
   > 
   >     package Foo;
   >     use vars qw/$line/; # can't use our as that also creates a lexical :(
   > 
   >     $line = 0;
   >     my $func = sub {
   >         print $line++, ' ', shift(), "\n";
   >     };
   > 
   >     Test::apply($func, qw(a b c d));
   > 
   > In this case $func picks up $Foo::line rather than $Test::line or
   > $::line, even though it's anonymous.

   It's still a closure. Perl 5 just isn't a good example here, since all 
   anonymous subs are closures.

   Allison

It is not closing over $Foo::line, though, which is a free reference to
a global, and not a lexical.  (It doesn't need to be a closure at all,
because AFAICS there are no lexicals in scope.)

   But this just seems to show that the namespace name really belongs to
the global, not to the sub.  In other words, this should compile to code
that uses

                line = get_global ['Foo'], '$line'

rather than

                line = get_global '$line'

and similarly for set_global.

   So the real question is this:  Do we even need the two-arg forms of
get_global and set_global, or are these just sources of confusion?
After all, the namespace argument could always be filled in by IMCC,
since it's fixed at compile time.

   From: Allison Randal <[EMAIL PROTECTED]>
   Date: Wed, 22 Nov 2006 20:36:53 -0800

   . . .

   . . . One common use of anonymous subs in a dynamic language is 
   for later exporting them into another package (or multiple different 
   packages). In that case, you really don't want the sub to retain a link 
   to its defining namespace, you want it to fully adopt the namespace it's 
   pushed into. Which has everything to do with the earlier Perl example of 
   creating anonymous subroutines, but little to do with creating "main" 
   routines, since they don't change packages. (Code examples are helpful.)

   Let's see... for :main, :load, :method, and :vtable compilation units it 
   makes sense to default lookups to the namespace where they were defined, 
   even if they're anonymous. For an ordinary :anon .sub (with no :vtable, 
   :method, :load, :main, etc) I could argue it either way, but with the 
   other uses remaining tied to the namespace where they were defined, 
   let's default to your fix (consistency is good).

   Then for exporting (and other dynamic tricks), let's look into a feature 
   that allows you to change the namespace a compilation unit uses for 
   default lookups, after it's compiled.

   Allison

"Full adoption" seems problematic to me.  What if the end of this code
(as revised by Ben) is changed to this:

        # new magic.
        *Baz::other_func = $func;

        # . . . and some time later:
        Test::apply(\&Baz::other_func, qw(a b c d));

Are you saying that \&Baz::other_func should access the (undeclared)
$Baz::line variable, instead of $Foo::line ?  And what about this:

        # multiple magic.
        *Baz::other_func = $func;
        *Quux::still_another_func = $func;

Should &Baz::other_func and &Quux::still_another_func reference the same
or different globals?  IMHO, if the programmer intended the answer to be
"different globals" at runtime, s/he could have written this with
explicit glob manipulation.  Or, better still, used a closure.

                                        -- Bob

Reply via email to