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

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=

Replies are listed 'Best First'.
Re^4: Accessing lexicals in other scopes dynamically by name
by morgon (Priest) on Jul 30, 2010 at 17:48 UTC
    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.
        Hmm.

        I have never really looked at the Perl-internals, but I can vagly remember having seen an implementation of Scheme in Scheme.

        If I remember correctly there was a data-structure containing all the variable-bindings for any lexical scope and every closure would simply keep a reference to this.

        So in this approach there is not a "capturing of all lexicals" but simply remembering one data-structure regardless of how many variables were defined it.

        Perl evidently does this differently and I even think that the inaccessabilty of certain lexial variables of which Perl could not see that the are going to be used in a closure is a weakness.

        I will try this in Rakudo.