Я обычно перебираю строки в файле, используя следующий код:
open my $fh, '<', $file or die "Could not open file $file for reading: $!\n";
while ( my $line = <$fh> ) {
...
}
Однако при ответе на другой вопрос , Эван Кэрролл отредактировал мой ответ,изменив мое while
утверждение на:
while ( defined( my $line = <$fh> ) ) {
...
}
Его логическое обоснование состояло в том, что если у вас есть строка с номером 0
(это должна быть последняя строка, в противном случае она будет иметь возврат каретки), тогдаваш while
преждевременно завершится, если вы использовали мое утверждение ($line
будет установлено в "0"
, и, следовательно, возвращаемое значение из присваивания также будет "0"
, что будет оценено как false).Если вы проверите для определенности, то вы не столкнетесь с этой проблемой.Это имеет смысл.
Так что я попробовал.Я создал текстовый файл, последняя строка которого 0
без возврата каретки.Я пропустил его через цикл, и цикл не завершился преждевременно.
Затем я подумал: «Ага, может быть, значение на самом деле не 0
, может быть, есть что-то еще, что испортило все!»Поэтому я использовал Dump()
из Devel::Peek
, и это то, что он дал мне:
SV = PV(0x635088) at 0x92f0e8
REFCNT = 1
FLAGS = (PADMY,POK,pPOK)
PV = 0X962600 "0"\0
CUR = 1
LEN = 80
Это, кажется, говорит мне, что значение на самом деле является строкой "0"
, поскольку я получаю аналогичный результат, еслиЯ звоню Dump()
на скаляре, который я явно установил на "0"
(единственное отличие - в поле LEN - из файла LEN - 80, тогда как из скалярного LEN - 8).
Так в чем же дело?Почему мой цикл while()
преждевременно не завершается, если я передаю ему строку, которая только "0"
без возврата каретки?Цикл Эвана на самом деле более оборонительный, или Perl делает что-то сумасшедшее внутренне, что означает, что вам не нужно беспокоиться об этих вещах, и while()
фактически завершается, только когда вы нажимаете eof
?