Reputation: 17
For some reason my original array gets wiped out with this code. I can't figure out why? @my_array is empty after running this, I took out all the work in the while loop to see if that was the cause but its not.
foreach (@my_array)
{
open MY_FH, "<", $_;
while (<MY_FH>)
{
}
close MY_FH;
}
Upvotes: 0
Views: 204
Reputation: 126772
As cjm has explained, the elements of the array are overwritten by the while
loop because it reads from the file into $_
, which the foreach
aliases to each array element in turn
The simplest solution is to localise $_
for the duration of the while
loop. That creates a temporary copy of $_
that can be used without affecting @my_array
. Like this
for ( @my_array ) {
open my $fh, '<', $_;
local $_; # To protect @my_array
while ( <$fh> ) {
...
}
close $fh;
}
Upvotes: 0
Reputation: 62109
It's not empty, it's just full of undef
.
while (<MY_FH>)
is syntactic sugar for while (defined($_ = <MY_FH>))
. Since the variable in a foreach
loop is an alias to the original value, the filename in $_
gets overwritten with each line of the file. The while
loop keeps going until <MY_FH>
returns undef
to indicate EOF. That undef
is the last value stored in $_
.
The solution is to use a different variable in at least one of the loops. Changing the foreach
loop will probably be less work:
foreach my $fn (@my_array)
{
open MY_FH, "<", $fn;
while (<MY_FH>)
{
}
close MY_FH;
}
If you checked the size of @my_array
after the loop with scalar @my_array
, you'd find that it hasn't changed. But an array of undef
looks just like an empty array when you're accessing individual elements, which is probably why you think it's empty.
Upvotes: 9