Я обычно перебираю строки в файле, используя следующий код:
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"
без возврата каретки? Является ли цикл Evan более защитным, или Perl делает что-то сумасшедшее внутренне, что означает, что вам не нужно беспокоиться об этих вещах, а while()
на самом деле выходит только при нажатии eof
?