On Sep 24, 2004, at 8:07 AM, 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.

Ha, you're example is actually wrong (but tricked me for a second). Here's a simpler case to demonstrate that you can't look up lexicals by name (in Perl5):


% perl -le '$x = 2; print ${"x"}'
2
% perl -le 'my $x = 2; print ${"x"}'

(printed nothing)

The first case prints 2 because $x is a global there; in the second case, it's a lexcial, and ${"x"} is looking for a global.

In your example, ${"foo"} is actually addressing the global $foo, not your lexical. To demonstrate, both this:

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

and this:

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

also print "012".

(Your example should have printed "123", if the lexical $foo had been what the closure was incrementing.)

Someone else suggested that you need this for string eval, but you don't
really. You need it for by-name lookups, which string evals just happen
to also need. If you can't do by-name lookups, then string eval doesn't
need pads (and thus won't be able to access locals).

String eval is special because without it, you can tell at compile time all of the places where a lexical is used (ie, you can trace all of the places it's used back to which declaration matches them), and obviate the need for a by-name lookup (since Perl5 doesn't allow explicit by-name lookups of lexicals). For string evals to work in the lexical scope in which they occur, you do have to have by-name lookups "behind-the-scenes". I believe that's all correct. And where this could be a savings is that, in any lexical scope in which there is no eval visible (looking down the tree of nested lexical scopes), then you don't need to save the name-to-variable mapping in nested pads. Add a call to eval, and you need to save a lot more stuff.


JEff



Reply via email to