in reply to Re: foreach localizing variables
in thread foreach localizing variables

Thanks for all the explanations.

Should have mentioned it's not actually my code! I've fixed it up, but just wanted to understand why it's doing what it's doing.

I'm still a bit confused though...

I get the fact that the compile time of the subroutine means it will use the initial variable. But does the localised variable not use the same location as the my variable?

Andrew

Replies are listed 'Best First'.
Re^3: foreach localizing variables
by shmem (Chancellor) on Feb 07, 2008 at 12:47 UTC
    My previous post wasn't quite accurate. The my $value marks that variable as lexical for the current scope, but a for() loop argument context gets its own store ("scratchpad", see perlguts), as is the case for subroutines. So, although at compilation the my() declaration extends into the sub, the variable inside the sub gets allocated on a different scratchpad, but is also marked as lexical (PADMY):
    use Devel::Peek; my $value = "four"; my @array = ( "one" ); warn "(1):\n" ; Dump($value); foreach $value (@array) { warn "(2):\n" ; Dump($value); print "foreach value: $value\t"; function(); sub function { warn "(3):\n" ; Dump($value); print "function value: $value\n"; } } __END__ (1): SV = PV(0x8b83b00) at 0x8b83768 REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK) PV = 0x8b992c8 "four"\0 CUR = 4 LEN = 8 (2): SV = PV(0x8b83c20) at 0x8b82c28 REFCNT = 2 FLAGS = (POK,pPOK) PV = 0x8b962c0 "one"\0 CUR = 3 LEN = 4 (3): SV = NULL(0x0) at 0x8b837b0 REFCNT = 2 FLAGS = (PADBUSY,PADMY) foreach value: one function value:

    As you can see, all addresses of $value are different. The my() just tells the compiler that the symbol $value is to be treated as a lexical variable for the scope in which it was declared, but that doesn't mean it has always the same storage (or only one address location). <update> The $value inside the sub inside the for() loop gets its own $value because the outer $value isn't visible in the scope in which it has been compiled.</update> Bare blocks are different:

    use Devel::Peek; my $value = "four"; warn "(1):\n" ; Dump($value); { $value = "five"; warn "(2):\n" ; Dump($value); } __END__ (1): SV = PV(0x8bcdb00) at 0x8bcd75c REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK) PV = 0x8bee7d0 "four"\0 CUR = 4 LEN = 8 (2): SV = PV(0x8bcdb00) at 0x8bcd75c REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK) PV = 0x8bee7d0 "five"\0 CUR = 4 LEN = 8
    Welcome to The Monastery, btw ;-)

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}