in reply to Re: Accessing lexicals in other scopes dynamically by name
in thread Accessing lexicals in other scopes dynamically by name

Note: Subs only capture variables it knows it will need.
I don't think that is true.

My understanding is that closures capture the whole environment (in the sense of lexical variable bindings).

Otherwise this would not be possible:

use strict; my $a = 1; my $b = 2; my $c = 3; sub f { my $var = shift; print $var, "=", eval "\$$var", "\n"; }; &f("a"); &f("b"); &f("c"); # prints a=1 b=2 c=3

Replies are listed 'Best First'.
Re^3: Accessing lexicals in other scopes dynamically by name
by ikegami (Patriarch) on Jul 30, 2010 at 16:59 UTC

    Nothing's captured. $a, $b, $c are still in scope, and we've already established that eval should and can access lexicals in scope.

    Place all by the calls to f() in curlies or in a module and you'll see it doesn't capture.

    use strict; { my $a = 1; my $b = 2; my $c = 3; sub f { my $var = shift; print $var, "=", eval "\$$var", "\n"; }; } &f("a"); &f("b"); &f("c");
    $ perl -w a.pl Variable "$a" is not available at (eval 1) line 2. Use of uninitialized value in print at a.pl line 11. a= Variable "$b" is not available at (eval 2) line 2. Use of uninitialized value in print at a.pl line 11. b= Variable "$c" is not available at (eval 3) line 2. Use of uninitialized value in print at a.pl line 11. c=
      ikegami, you are right.

      Does anyone have any idea why Perl does it like that?

      I mean to implement it like this must be more difficult than simply to keep a pointer to the whole enviroment for every closure.

      What is the motivation?

        I think it's an optimisation. Capturing all lexicals would cause a closure to take longer to create, use more memory and prevent another optimisation that reuses lexicals from previous calls to the function.