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