in reply to Re^2: How do closures and variable scope (my,our,local) interact in perl?
in thread How do closures and variable scope (my,our,local) interact in perl?

.. but when the same is done in a loop, with a lexical variable declared beforehand, the result changes:

because a loop is a block of it's own which changes. IIRC the essence of closures is that whenever the outer block is entered (decided at run-time!) the my variables are associated to another lexpad (please correct my terminology if I name something wrong).

so with

for my $var ( 1,2,3) { my $x =sub {print $var } }

the opcode for $var points for each run into different instances of the lexpads of the for loop.

UPDATE ----

it's more like this in pseudocode

while ( $LEXPAD{for-block}={}; "$LEXPAD{for-block}"->{var} = (1,2,3)- +>next() ) { my $x =sub { print "$LEXPAD{for-block}"->{var} } }

----- UPDATE

OTOH there is nothing like a "closure with packagevars", they always point to the same symboltable (decided at compile-time!)

Now the extra complexity comes because ELISHEVA declares the loop variable in advance with my / our, which implies localising, i.e. saving and restoring the variable at runtime. (Nota bene: Normally there is nothing like local() with lexvars)

Cheers Rolf

Replies are listed 'Best First'.
Re^4: How do closures and variable scope (my,our,local) interact in perl?
by Corion (Patriarch) on Jun 16, 2009 at 16:14 UTC

    You'll note that I didn't use the for my version. I feel that for $name should behave identically whether $name is a lexical or a global variable, as the same variable is visible outside the for block in both cases. The two variables live in two separate namespaces, which is the likely cause for the phenomenon we see, but as their visibility is identical, that shouldn't affect behaviour. The "localising" still shouldn't affect lexical variables in a way different to global variables, but it seems to do. This might warrant some mention in the documentation.

      I know, just wanted to simplify the case before entering the mentioned "extra complexity".

      There are some extra phenomenons complicating and maybe explaining it ...

      1. The loop-variable is an alias to the current list element

      2. Normally there is no local() for lexvars, maybe they needed to implement a work-around.

      My guess is, the programmers decided to implement this "local(lexical loop-var)" by associating it temporarily to the loops lexpad.

      This might warrant some mention in the documentation.

      definitely!

      Cheers Rolf

      UPDATE: deleted wrong passage...