in reply to Re^3: Easiest way to do something only on first iteration of loop
in thread Easiest way to do something only on first iteration of loop

Hello Marshall,

When it [a state variable] is "out of scope", then next time it comes into scope it is reinitialized.

Sorry to be pedantic, but no, as the documentation says, it is never reinitialized. Consider:

use strict; use warnings; use feature qw( say state ); my $x = 42; for (1 .. 2) { for (1 .. 3) { state $x; ++$x; say "\$x = $x"; } say "state \$x is out of scope here"; say "\$x = $x"; }

Output:

16:48 >perl 1626_SoPW.pl $x = 1 $x = 2 $x = 3 state $x is out of scope here $x = 42 $x = 4 $x = 5 $x = 6 state $x is out of scope here $x = 42 16:48 >

When the inner for loop ends, state $x goes out of scope and the $x that is printed is the my $x with wider scope. But when the inner for loop is re-entered, the inner-scope $x (the state variable) retains the value it had previously: it is not reinitialized.

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^5: Easiest way to do something only on first iteration of loop
by Marshall (Canon) on May 08, 2016 at 12:21 UTC
    Athanasius Thank you for the correction!

    I played with your code and even if the for loops are in a subroutine, the state version of $x is never re-initialized. In the documentation, my brain got stuck when the first sentence compared it to a my variable, causing a brain cramping mis-reading of the rest! Great that we have more eyeballs than mine on this stuff!

    One thing I didn't test was behavior in threads. I am not sure what would happen.

      One thing I didn't test was behavior in threads. I am not sure what would happen.

      As with all variables that are not explicitly shared, each thread gets its own copy of any state variable; but within that thread it performs consistently with its behaviour in 'non-threaded' (single-threaded) code as you would expect:

      CC:\test>perl -Mthreads -E" async{ for(1..4){ state $x = 123; say thre +ads->tid, ':', $x++ } }->join for 1 .. 4" 1:123 1:124 1:125 1:126 2:123 2:124 2:125 2:126 3:123 3:124 3:125 3:126 4:123 4:124 4:125 4:126

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.