Why does calling this function change my array?

Perl seems to be killing my array whenever I read a file:

my @files = ("foo", "bar", "baz");
print "Files: " . join(" ", @files) . "\n";

foreach(@files) {
   print "The file is $_\n";
   func();
}

sub func {
   open(READ, "< test.txt");
   while(<READ>) {
   }
   close READ;
}

print "Files: " . join(" ", @files) . "\n";

produces:

Files: foo bar baz
The file is foo
The file is bar
The file is baz
Files:

but when I comment out func(), it gives what I would've expected:

Files: foo bar baz
The file is foo
The file is bar
The file is baz
Files: foo bar baz

Any ideas why this might be happening?

Answers


You have to change foo to localize $_, or not to use $_ in your loop. Best yet, do both:

foreach my $filename (@files) {
    print "The file is $filename\n";
    func();
}

sub func {
    local $_;
    open my $read, '<', 'test.txt' or die "Couldn't open test.txt: $!";
    while(<$read>) {
    }
    close $read or die "Couldn't close file: $!";
}

The foreach loop aliases $_ to the current name of the file and the while(<READ>) assigns to $_. That's a bad combination of magic, so to say.

In general, it's a bad idea to rely on much on $_ for anything other than a one-liner.


Need Your Help

How do I iterate through two arrays individually

arrays ruby iterator zip enumerator

My own little project is to merge two logs based on timestamps, both logs have the same timestamp. Some rows do not have timestamps and should be printed with the row with timestamp.

PHP pThreads IIS: unexpected output in browser

php multithreading iis pthreads

I'm attempting to have a php script run multi-threaded using PHP pThreads in a IIS 7 PHP 5.6 x86 (thread safe) environment. I've created a github issue but I haven't heard back and though some other