in reply to Re: Using an "outer" lexical in a sub?
in thread Using an "outer" lexical in a sub?

Hm... I just tried something which, to me, looks like it should behave the same as the above code, but it won't do the same trick:
#!/usr/bin/perl use strict; use warnings; my $ref1; my $ref2; { my $n = 10; $ref1 = sub { print( $n++, "\n" ) }; $ref2 = sub { print( $n++, "\n" ) }; } $ref1->(); # --> 10 $ref1->(); # --> 11 $ref1->(); # --> 12 print "\n"; $ref2->(); # --> 13 Huh? $ref2->(); # --> 14 ? $ref2->(); # --> 15 ?

I'd expect that first call to $ref2->(); to start up with its own squirreled-away $n (starting at 10). Why doesn't it?

Replies are listed 'Best First'.
Re^3: Using an "outer" lexical in a sub?
by Joost (Canon) on Nov 01, 2006 at 22:03 UTC
    It doesn't start with it's own version of $n, because at the time you're creating $ref1 and $ref2 $n is the same variable.

    You can look at it like this:

    sub test() { my $n = 10; { print( $n++, "\n" ) } { print( $n++, "\n" ) } print "\$n is now $n\n; }
    Now, you can see that both blocks access the same variable (i.e. $n will be 12 at the end of test()).

    If you run test() again, my $n = 10; will effectively be a new variable $n but if you still have a subref somewhere that accesses the old $n (i.e. a reference to a to one or more of the inner blocks) that code ref will hang on to its variables and new ones will be created if necessary.

    Note that in my earlier post the outer subroutine is called twice and that will create the new lexical variable.

      It doesn't start with it's own version of $n, because at the time you're creating $ref1 and $ref2 $n is the same variable.

      Doh! Thanks Joost (and imp). :)

      #!/usr/bin/perl use strict; use warnings; my $ref1; my $ref2; { my $n = 10; $ref1 = sub { print( $n++, "\n" ) }; } { my $n = 10; $ref2 = sub { print( $n++, "\n" ) }; } $ref1->(); # --> 10 $ref1->(); # --> 11 $ref1->(); # --> 12 print "\n"; $ref2->(); # --> 10 $ref2->(); # --> 11 $ref2->(); # --> 12
Re^3: Using an "outer" lexical in a sub?
by imp (Priest) on Nov 01, 2006 at 22:00 UTC
    { my $n = 10; $ref1 = sub { print( $n++, "\n" ) }; $ref2 = sub { print( $n++, "\n" ) }; }
    When the anonymous subroutine that is stored in $ref1 is created it increases the reference count for that instance of $n to 2.

    When the anonymous subroutine that is stored in $ref2 is created it increases the reference count for that instance of $n to 3.

    The two anonymous subroutines share the same $n in this case.