in reply to Re^2: Closure confusion in Tkx (declarations in loops - inner vs outer)
in thread Closure confusion in Tkx

Thanks Rolf!

The code works now but I'm still kinda puzzled as to why the c-style for fails in this case. Is this not a bug in perl?

Regards,

Lars

  • Comment on Re^3: Closure confusion in Tkx (declarations in loops - inner vs outer)

Replies are listed 'Best First'.
Re^4: Closure confusion in Tkx (declarations in loops - inner vs outer)
by AnomalousMonk (Archbishop) on Jul 13, 2019 at 22:01 UTC

    I agree with LanX's explanation here, but here's something I put together that may provide a different viewpoint.

    In the C-style for-loop and in its while-loop equivalent in LanX's examples here, a closure is formed (if that's the correct term) over two variables, $i and $x. The $i variable is created anew in each iteration through each loop (there's a  my $i = ...; within the scope of the loop), but the $x variable is created only once (in each example). Therefore, the closures are over three different versions of a variable named $i, each of which can have a different value, but only over a single version of a variable named $x, which has the value it ends up with at the end of each of the loops.

    In the Perl-style loop example here, the for-loop iterator variable $i is successively aliased to three individual values, each of which individually has a closure formed over it and so can reflect those three values independently; you're seeing the alias of $i in each case and not the value of $i.

    Or so I think...

    Update: And no, the way the C-style for-loop works in Perl is not a bug; it's the way closures work.


    Give a man a fish:  <%-{-{-{-<

Re^4: Closure confusion in Tkx (declarations in loops - inner vs outer)
by LanX (Saint) on Jul 13, 2019 at 21:35 UTC
    > as to why the c-style for fails in this case.

    Think of lexicals in a scope like having a different references each time the scope is passed at runtime.

    But - like already demonstrated - the first part of the c-style for is outside the block to be implemented as a while.

    More gory details?

    A lexical declaration in a scope reserves - at run time - a storage place in memory which is released at the end of scope.

    No release happens if the ref counter isn't 0, like when the lexical is used in a closure.

    So if the last lexical was released it might happen that the ref is reused, but it's better to assume they aren't the same variable.

    DB<8> for my $x (1..3) { print \$x } SCALAR(0x3450e50)SCALAR(0x3450e50)SCALAR(0x3450e50) DB<9> for my $x (1..2) { print \$x; $a = sub {$x} } SCALAR(0x3459b20)SCALAR(0x3328238)

    $x has different refs in line 9 because the first $x is captured in a closure and not relased.

    Hence Perl can't reuse the reference.

    HTH! :)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice