On Sep-24, Aaron Sherman wrote:
> On Fri, 2004-09-24 at 10:03, KJ wrote:
> 
> > So, my question is, why would one need lexical pads anyway (why are they 
> > there)?
> 
> They are there so that variables can be found by name in a lexically
> scoped way. One example, in Perl 5, of this need is:
> 
>       my $foo = 1;
>       return sub { $foo ++ };
> 
> Here, you keep this pad around for use by the anon sub (and anyone else
> who still has access to that lexical scope) to find and modify the same
> $foo every time. In this case it doesn't look like a "by-name" lookup,
> and once optimized, it probably won't be, but remember that you are
> allowed to say:
> 
>       perl -le 'sub x {my $foo = 1; return sub { ${"foo"}++ } }$x=x();print $x->(), 
> $x->(), $x->()'
> 
> Which prints "012" because of the ability to find "foo" by name.

Umm.... maybe I"m confused, but I'd say that your example prints "012"
because of the *inability* to find "foo" by name. If it could find "foo"
by name, it would be printing 123. Your snippet is actually finding the
global $main::foo, not the lexical $foo.

But I agree that it is doing a name lookup in the string eval case.
Although if you try it, you get puzzling results:

 perl -le 'sub x {my $foo = 1; return sub { eval q($foo++) } };$x=x();print
$x->(), $x->(), $x->()'

prints 012 again. Which confused me, because Perl *can* do named lookups
of lexicals. The problem, apparently, is that it's doing the lookup but
not finding it. If you add in a nonsensical use of $foo to make sure it
sticks around to be found, it works:

 perl -le 'sub x {my $foo = 1; return sub { $foo; eval q($foo++) }
};$x=x();print $x->(), $x->(), $x->()'

Now apparently the closure captures the lexical $foo, and thus the eval
is able to find it. On the other hand, your original example still
doesn't work, and I think that's because symbolic references do not do
pad lookups:

 perl -le 'sub x {my $foo = 1; return sub { $foo; ${"foo"}++ } }$x=x();print
$x->(), $x->(), $x->()'

still prints 012.

Yep. From perlref:

  Only package variables (globals, even if localized) are visible
  to symbolic references.  Lexical variables (declared with my())
  aren't in a symbol table, and thus are invisible to this
  mechanism.  For example:

Reply via email to