On 9/20/07, flw <[EMAIL PROTECTED]> wrote: > C:\>cat ttt.pl > use strict; > use warnings; > > { > my $x = 'A'; > sub f { sub { $x++ } } > sub g { sub { $x++ } if $x } > } > > my $F=f(); > my $G=g(); > > print $F->(),$G->(),"," for 1..4; > print "\n"; > > C:\>ttt.pl > 0A,1B,2C,3D, > > C:\>
Known bug in closure implementation. Since sub f doesnt mention $x the sub that it returns doesnt enclose the same $x as the sub returned by g(). Changing the code to read { my $x = 'A'; sub f { sub { print \$x; $x++ } } sub g { sub { print \$x; $x++ } if $x } } Produces: SCALAR(0x225f18) SCALAR(0x226d4c) 0A, SCALAR(0x225f18) SCALAR(0x226d4c) 1B, SCALAR(0x225f18) SCALAR(0x226d4c) 2C, SCALAR(0x225f18) SCALAR(0x226d4c) 3D, Which shows that the two are operating on different scalars. I had guessed that the f() sub would be operating on $::x but it turns out that it isnt. Somehow *two* $x'es are being created. Which i find surprising even though i know about this bug. The solution is to add a dummy line to f() to make sure that it mentions $x. { my $x = 'A'; sub f { my $y=$x; sub { print \$x; $x++ } } sub g { sub { print \$x; $x++ } if $x } } Will cause both subs to bind to the same scalar. Cheers, Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"