Я обычно перебираю строки в файле, используя следующий код:
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?