Why is there no warning thrown for the redeclaration of $i
in the following code?
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
for my $i (1..3) {
my $i = 'DUMMY';
print Dumper $i;
}
Why is there no warning thrown for the redeclaration of $i
in the following code?
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
for my $i (1..3) {
my $i = 'DUMMY';
print Dumper $i;
}
From man perlsyn:
The foreach loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn.
Because of this aliasing, the iteration variable is always localized to the loop, no matter how it is declared. Consider this example:
my $x = 1;
for $x (2..3) { }
print $x; # 1, never changed
Next, see what flags are set for the iterator variable in your case:
use Devel::Peek;
for my $i ( 1 ) { # just one iteration
Dump $i;
}
SV = IV(0x81178c8) at 0x8100bf8
REFCNT = 2
FLAGS = (IOK,READONLY,pIOK)
IV = 1
Oops. There's no PADMY
flag here, which would indicate that its a lexical variable, declared with my
.
I hope this explains why there's no warning thrown for the redeclaration of $i in your example..
Actually, you only get warnings for redefinitions in the same scope. Writing:
use warnings;
my $i;
{
my $i;
# do something to the inner $i
}
# do something to the outer $i
is perfectly valid.
I am not sure if the perl internals handle it this way, but you can think of your for-loop as being parsed as
{
my $i;
for $i ( ... ) { ... }
# the outer scope-block parens are important!
};