in reply to Re: Trying to understand closures
in thread Trying to understand closures

No, no optimization was involved. Don't confuse my $x with undef $x. my $x does NOT change the value of $x. Aside from returning $x's value, all my $x does is set a flag to clear $x at the end of the current scope (i.e. at the end of the loop pass).

Can you guess what the following snippet prints?

for (1..4) { my $x; print ++$x; } print "\n"; for (1..4) { goto SKIP if $_ == 2; my $y; SKIP: print ++$y; } print "\n"; for (1..4) { my $z if $_ != 2; print ++$z; }

At the end of every pass of the first loop, $x gets cleared, so the output of that loop is 1111.

At the end of every pass *except the second* of the second loop, $y gets cleared, so the output of that loop is 1121.

The third loop is identical to the second one. It also outputs 1121.

Updated: Reworded for clarity. No new content.
Updated: Added code.

Replies are listed 'Best First'.
Re^3: Trying to understand closures
by superfrink (Curate) on Nov 24, 2006 at 05:51 UTC
    my $x does actually change the value of $x .

    Update: That's wrong. I don't know why I wrote that. As far as I know my creates a new variable so the later references to $x actually refer to a different instance of a variable even though they have the same name.

    For example this code:
    print __LINE__ . ": $x\n"; my $x = 123; print __LINE__ . ": $x\n"; my $x = 456; print __LINE__ . ": $x\n"; my $x; print __LINE__ . ": $x\n";
    Prints out:
    1: 3: 123 5: 456 7:

      Each of those $x is a different variable.

      "my" variable $x masks earlier declaration in same scope at 585826.pl +line 4. "my" variable $x masks earlier declaration in same scope at 585826.pl +line 6. print __LINE__ . ": " . \$x . " = $x \n"; my $x = 123; print __LINE__ . ": " . \$x . " = $x \n"; my $x = 456; print __LINE__ . ": " . \$x . " = $x \n"; my $x; print __LINE__ . ": " . \$x . " = $x \n";
      1: SCALAR(0x0225fc4) = 3: SCALAR(0x022603c) = 123 5: SCALAR(0x1830b1c) = 456 7: SCALAR(0x1830ba0) =

      (Undefined warnings omitted.)

      Note that my $x does not always create a new variable. In my snippet, $x, $y and $z are the same variable every pass through the loop.

Re^3: Trying to understand closures
by gam3 (Curate) on Nov 24, 2006 at 13:01 UTC
    Can you guess what the following snippet prints?
    for (1..4) { my $x; print ++$x, " ", \$x, "\n"; sub { $y = $x }; }
    And this?
    for (1..4) { my $x; print ++$x, " ", \$x, "\n"; sub bob { $y = $x }; }
    And now the answer: In the first case there is no closure, so only one $x is created, but in the second case there is a closure so 2 different $xs are created as you can see from the output.

    for example:

    1 SCALAR(0x8160300)
    1 SCALAR(0x8160300)
    1 SCALAR(0x8160300)
    1 SCALAR(0x8160300)
    
    1 SCALAR(0x81649e8)
    1 SCALAR(0x814cd38)
    1 SCALAR(0x814cd38)
    1 SCALAR(0x814cd38)
    
    -- gam3
    A picture is worth a thousand words, but takes 200K.