2

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.

1
  • if(@data){ for(@data){ ... } } is a unnecessarily complex way of writing for(@data){ ... } Commented Dec 11, 2014 at 19:50

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

even if it weren't passed to the subroutine, the while loop (shorthand for while ( defined( $_ = <$fh> ) ) would still be changing the array values (because the for aliases $_ to them). Using variables other than $_ in both the for loop and the while loop would be a good idea (though just changing the for fixes this problem)
Thanks very much. I just changed all default variables for defined ones.
1
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.