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
блоки очень полезны (и недоиспользуются); это отличный способ иметь лексический блок выполнения, но все же легко вернуть что-то во внешнюю область.