When you write code, ALWAYS INDENT CORRECTLY. It's difficult to see how the code executes, and it also can hide errors when code is poorly indented. Also, always use white space and don't double up statements. 90% of programming is maintenance, so what little extra typing you do to make your code easy to understand saves a ton of time in maintaining it.
I've reinvented your code, so I could read it.
When you use my
to declare a variable, you are declaring it as a lexically scoped. What this means is that it is defined in a limited context. This is ususally a good thing. It means variables disappear when you no longer need them. However, it also means that variables disappear when you need them.
my
variables live in the block where they're defined. If the are defined inside a while/until
loop, they live within that while loop. Once you exit the while
, they go bye-bye. Same thing with an if
statement or a for
loop. In fact, if you just put curly braces, the my
variable, if defined in those curly braces will lose it's definition once outside:
{
my $foo = "bar";
}
print "$foo\n"; # Whoops, $foo is undefined!
If you need a variable to live outside of the loop, it needs to be defined outside of that loop:
my $odd_count = 0;
for my $number ( @number_list ) {
if ( $number % 2 ) {
$odd_count++;
}
}
print "There are $odd_count numbers in my list\n";
You can also end up redefining a variable if you redeclare it with my
:
use warnings;
use strict;
use feature qw(say);
my $foo = "bar";
{ # New block!
say "Initial value of \$foo: $foo";
my $foo = "foo"; # Using "my" on $foo
say "Changed value of \$foo: $foo";
}
say "Final value of \$foo: $foo";
If you run this, you'll get:
Initial value of $foo: bar
Changed value of $foo: foo
Final value of $foo: bar
That's because you've redeclared $foo
inside the block, so you now have a new variable $foo
that will cover the old value of $foo
until the block ends. Once the block ends, the old
$foo` variable is back, with its old value:
my $foo = "bar";
{ # New block!
say "Initial value of \$foo: $foo";
$foo = "foo"; # No "my" on $foo
say "Changed value of \$foo: $foo";
}
say "Final value of \$foo: $foo";
If you run this, you'll get:
Initial value of $foo: bar
Changed value of $foo: foo
Final value of $foo: foo
In this case, I removed the my
. Now when I say $foo = "foo";
, I'm using the same $foo
I defined outside the block, so once I leave the block, $foo
will still have its old value.