Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am confused about the behavior of the subroutine that used a variable, which was declared by "my" twice in main.

use warnings; my $s = "s1"; print "define var: $s\n"; &test; my $s = "s1-2nd"; print "define var: $s\n"; &test; sub test{ print "sub: $s\n"; }

Result from the above code:

"my" variable $s masks earlier declaration in same scope at test.pl li +ne 8. define var: s1 Use of uninitialized value $s in concatenation (.) or string at test.p +l line 13. sub: define var: s1-2nd sub: s1-2nd

So the second call of &test didn't have the $s value. If I only used one "my" at the beginning (i.e. use $s = "s1-2nd", instead of my $s = "s1-2nd"), it behaved like I expected, the subroutine &test gave the value of $s each time it was called. But as shown above, by just adding "my" and declaring the $s second time, the first call of &test had $s value as uninitialized. Why did this happen?

If I placed the subroutine at the beginning, such as:

use warnings; my $s = "s1"; print "define var: $s\n"; &test; sub test{ print "sub: $s\n"; } my $s = "s1-2nd"; print "define var: $s\n"; &test;

This time, the result is:

"my" variable $s masks earlier declaration in same scope at test.pl li +ne 12. define var: s1 sub: s1 define var: s1-2nd sub: s1

So the second call of &test did have the $s value but the value was from the first declaration. Why did the second $s value not overwrite the first when there is a second "my"?
Again, if I simply remove the second "my", the result would be expected:

define var: s1 sub: s1 define var: s1-2nd sub: s1-2nd

Thanks in advance for your kind reply.

ark

Replies are listed 'Best First'.
Re: how subroutine functions when declare "my" twice in main
by LanX (Saint) on Nov 04, 2013 at 18:34 UTC
    The $s in the sub is a closure to the last declaration of $s before the sub was compiled.

    So when you call it at runtime before it was initialized it's of course undefined.

    (my does declaration at compile time and initialization at run time)

    Sorry if I don't elaborate more on "broken" code, just don't do this ... there is a reason why you get warnings! :)

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      Thanks much.