Reputation: 370
I got a problem with a Perl script.
Here is the code:
use strict;
use Data::Dumper;
my @data = ('a','b');
if(@data){
for(@data){
&debug_check($_)
}
}
print "@data";#Nothing is printed, the array gets empty after the while loop.
sub debug_check{
my $ip = shift;
open my $fh, "<", "debug.txt";
while(<$fh>){
print "$_ $ip\n";
}
}
Array data, in this example, has two elements. I need to check if the array has elements. If it has, then for each element I call a subroutine, in this case called "debug_check". Inside the subroutine I need to open a file to read some data. After I read the file using a while loop, the data array gets empty.
Why the array is being flushed and how do I avoid this strange behavior?
Thanks.
Upvotes: 2
Views: 65
Reputation: 385657
while (<$fh>)
is short for
while (defined($_ = <$fh>))
$_
is currently aliased to the element of @data
, so your sub is replacing each element of @data
with undef
. Fix:
while (local $_ = <$fh>)
which is short for
while (defined(local $_ = <$fh>))
or
while (my $line = <$fh>) # And use $line instead of $_ afterwards
which is short for
while (defined(my $line = <$fh>))
Be careful when using global variables. You want to localize them if you modify them.
Upvotes: 1
Reputation: 53478
The problem here I think, will be down to $_
. This is a bit of a special case, in that it's an alias to a value. If you modify $_
within a loop, it'll update the array. So when you hand it into the subroutine, and then shift
it, it also updates @data
.
Try:
my ( $ip ) = @_;
Or instead:
for my $ip ( @array ) {
debug_check($ip);
}
Note - you should also avoid using an &
prefix to a sub. It has a special meaning. Usually it'll work, but it's generally redundant at best, and might cause some strange glitches.
Upvotes: 1