элементы массива удаляются при зацикливании файлов - PullRequest
5 голосов
/ 15 апреля 2019

У меня проблема с циклическим просмотром имен файлов, элементы входного массива удаляются.

КОД:

use Data::Dumper;
use warnings;
use strict;


my @files = ("file1", "file2", "file3");

print Dumper(\@files);

for (@files) {
        my $filename = $_ . '.txt';
        open(my $fh, '<:encoding(UTF-8)', $filename)
          or die "Could not open file '$filename' $!";
        while(<$fh>) {
                print "$filename read line \n";
        }
}
print Dumper(\@files);

ВЫВОД:

$VAR1 = [
          'file1',
          'file2',
          'file3'
        ];
file1.txt read line
file2.txt read line
file3.txt read line
$VAR1 = [
          undef,
          undef,
          undef
        ];

СОДЕРЖАНИЕ ФАЙЛА:

 cat file1.txt
asdfsdfs
 cat file2.txt
iasdfasdsf
 cat file3.txt
sadflkjasdlfj

Почему содержимое массива удаляется? (У меня есть 2 разных решения этой проблемы, но я хотел бы понять, в чем проблема с этим кодом.)

Ответы [ 2 ]

7 голосов
/ 15 апреля 2019
while (<$fh>)

- это сокращение от

while ($_ = <$fh>)

, поэтому вы получаете $_, который имеет псевдоним для элемента @files.Вам нужно защитить $_ следующим образом:

while (local $_ = <$fh>)

Еще лучше, используйте другое имя переменной.

while (my $line = <$fh>)
4 голосов
/ 15 апреля 2019

Вы используете $_ двумя разными способами внутри цикла (в качестве текущего имени файла и в качестве текущей строки), и они забивают друг друга.Не делай этого.Назовите свои переменные, например:

for my $file (@files) {
    ...
    while(my $line = <$fh>) {
        ...
    }
}

Вы можете представить, что ваш текущий код делает это после чтения каждого файла:

for (@files) {
   undef $_;
}
...