Какой самый защитный способ перебрать строки в файле с помощью Perl?

Я обычно просматриваю строки в файле, используя следующий код:

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" , которое оценивается как ложное). Если вы проверите определенность, вы не столкнетесь с этой проблемой. В этом есть смысл.

Я попробовал. Я создал текстовый файл с последней строкой 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).

Так в чем же дело? Почему не t мой цикл while () завершится преждевременно, если я передаю ему строку, содержащую только «0» без возврата каретки? Является ли цикл Эвана более защитным, или Perl делает что-то сумасшедшее внутренне, что означает, что вам не нужно беспокоиться об этих вещах, и while () на самом деле завершается только тогда, когда вы нажимаете eof ?

14
задан Community 23 May 2017 в 12:26
поделиться