Почему вызов этой функции меняет мой массив? - PullRequest
4 голосов
/ 03 декабря 2008

Perl убивает мой массив всякий раз, когда я читаю файл:

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";

производит:

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

но когда я комментирую func(), это дает то, что я ожидал:

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

Есть идеи, почему это может происходить?

1 Ответ

12 голосов
/ 03 декабря 2008

Вы должны изменить foo, чтобы локализовать $_, или не использовать $_ в цикле. Лучше всего, сделайте оба:

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: $!";
}

В цикле foreach псевдоним $_ присваивается текущему имени файла, а while(<READ>) присваивается $_. Это плохая комбинация магии, так сказать.

В общем, плохая идея полагаться на $_ во всем, кроме однострочного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...