Perl - проблема с сохранением файла

Я запускаю следующий код:

open my $fh, "<", $file;

$/ = undef;
my $report = <$fh>;
$/ = "\n";

close $fh;

print("$report\n\n");

$ file ссылается на текстовый файл, который выглядит следующим образом:

a    1
b    2
c    3

Я запускал этот код на двух разных компьютерах с Linux. Один из них дал мне ожидаемый результат (именно так, как он отображается в текстовом файле). Другой дал мне это вместо этого:

GLOB(0x80f1174)

... что эффективно мешает мне дальше манипулировать содержимым.

Я проверил версии Perl - одна дает мне ожидаемый результат 5.10, а другая 5.8. Однако в прошлом я выполнял точно такой же код для аналогичных файлов с 5.8, который работал.

Я также пытался преобразовать файл из DOS в UNIX через:set ff=unix, но безрезультатно.

4 ответа

Неработающий файл не содержит

my $report = <$fh>;    # aka: readline($fh)

Возможно, он содержит

my $report = $fh;
my $report = < $fh >;  # aka: glob(" $fh ") = " GLOB(0xXXXXXXX) "
my $report = <$fh >;   # aka: glob("$fh ")  = "GLOB(0xXXXXXXX) "
my $report = < $fh>;   # aka: glob(" $fh")  = " GLOB(0xXXXXXXX)"

<> это ярлык для readline или же glob (никакого отношения к слову GLOB в выводе). Пространства заставляют это стать glob,

Я бы порекомендовал просто использовать модуль File::Slurp из CPAN. Тогда ваш код может выглядеть так:

use File::Slurp 'read_file';
my $file = '/path/to/some/file';
my $report = read_file $file;
print("$report\n\n");

Гораздо более читабельным и предсказуемым, ИМО.

Да пиши

<$fh>

так как $fh приведет к ошибкам, так как $fh это просто дескриптор файла. Печать будет эквивалентна печати ссылки. Такие, как приведенные ниже коды, запись как FH приведет к ошибке времени выполнения.

open FH,$infile or die$!;
while(<FH>){
    @line=split(/,/);
    if($flag==0){
     foreach my $col (@line){
      $header{$col}=$count;
      $count++;
     }
 }
}
close(FH);

Можно использовать File::Slurp, как рекомендует Hercynium, механизм, который ближе к тому, как выглядит ОП:

my $report = do {
  open my $fh, '<', $file;
  local $/;
  <$fh>;
};

Когда все сделано таким образом, все изменения являются локальными для do блок, включая закрытие дескриптора файла.

NB perldoc -f do говорит нам

сделать БЛОК

Не совсем функция. Возвращает значение последней команды в последовательности команд, обозначенной BLOCK.

Обратите внимание, что контекст последнего выполненного оператора является контекстом do block (здесь скаляр). я нахожу do блоки очень полезны (и недоиспользуются); это отличный способ иметь лексический блок выполнения, но все же легко вернуть что-то во внешнюю область.

Другие вопросы по тегам