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

> It would be a bit silly if one couldn't do

Sure ... but...

> Note: Subs only capture variables it knows it will need.

which was exactly my intuition, you understand my confusion, since

my enclosed sub from the OP:

$getset=sub { my ($name,$val)=@_; eval('$'.$name."='".$val."'"); # I can access any variable in this + scope };

doesn't know it will need to capture $x!

So whats happening here?

Cheers Rolf

Replies are listed 'Best First'.
Re^3: Accessing lexicals in other scopes dynamically by name
by ikegami (Patriarch) on Jul 30, 2010 at 16:54 UTC
    You never captured $x. It was simply still in scope. You basically did
    my $x="global"; my $test=sub { my $x="pre"; alert($x); # pre my ($name,$val)=@_; eval('$'.$name."='".$val."'"); alert($x); # post }
    which we've already established should work. Call the sub from outside the scope in which $x resides and you'll see it fail.
      >Call the sub from outside the scope in which $x resides and you'll see it fail.

      please define your understanding of "capture" and "scope" (dynamic or static).

      Cheers Rolf

        Capturing preserves a variable beyond the end of its normal scope.
        sub make_closure { my ($x) = @_; return sub { $x }; } my $c1 = make_closure("a"); my $c2 = make_closure("b"); say $c1->(); # a say $c2->(); # b

        The $x from the first call to make_closure and the $x from the second call to make_closure are kept alive beyond the end of their normal scope (the end of that call to make_closure).

Re^3: Accessing lexicals in other scopes dynamically by name
by LanX (Saint) on Jul 30, 2010 at 16:43 UTC
    Some changes to your code to make it clearer!

    use strict; use warnings; my $n="outer"; my $f; { my $n="ok"; $f=sub { eval "".shift }; check(); # "ok" }; sub check { print $f->('$n') } print $n; # "outer" exit;

    Cheers Rolf