[Israel.pm] Can anyone explain my mistake ?

sawyer x xsawyerx at gmail.com
Wed Jun 10 03:05:18 PDT 2009


People already answered this but I wanted to provide a more explanatory answer.
It's also kind of long, I hope that's okay with you.

> I am running this simple foreach loop:
> why do I get lv_num = <null> ? am I missing something ?
> Thanks
> Chanan
>
>
> my @arr = (1,2,3,4,5);
>
> foreach $lv_num (@arr)
> {
>   print "Found $lv_num\n";
>   last if ($lv_num == 3);
> }
>
> print "lv_num = $lv_num\n";

The way foreach works (without pasting the perldoc for it) is that it
runs a codeblock on each element in an array. foreach handles its own
codeblock, and localizes the variables outside the codeblock for its
own use.

Imagine what would happen if it didn't. If foreach would not localize
the variable for its own codeblock, this could occur:
my @arr = ( 1 .. 5 );
my $elm = 4;

foreach $elm (@arr) {
    print "$elm\n";
}
---
(the output would be:)
4
5

Why? because the element was predefined as 4, and in our crazy little
world foreach doesn't localize the variable, it uses the original
value.
Imagine what would happen if you had this:
my @arr = ( 1.. 5, 0, -1, 4 );
my $elm = 4;

foreach $elm (@arr) {
    print "$elm\n";
}
---

(what output would this be?)

So basically, foreach says "whatever it was, I'm gonna put it aside,
use the variable to iterate through the array, and then put the value
back the way it was before I touched it". This means that if you had
an uninitialized variable, used a foreach with it to iterate over an
array, and then printed the variable outside the foreach, it's still
uninitialized:
$ perl -W -le'my @a=(0..4); my $a; foreach $a (@a) { print $a } print $a;'
0
1
2
3
4
Use of uninitialized value in print at -e line 1. # <-- this is from
the print AFTER the foreach loop
---

So whatever value the variable had inside of the codeblock is removed
in favor of the original value when foreach is done. "Done" of course
refers to last; as well, since basically what you're saying is "lets
just get to the end of foreach right now". So, by having a value of 4
before the foreach, inside the foreach it will be the element in list
(for each iteration of it) and after it will return to be 4.

Did this answer your question?


More information about the Perl mailing list