¿Cuál es la forma más defensiva de recorrer líneas en un archivo con Perl?

Por lo general, recorro las líneas en un archivo usando el siguiente código:

open my $fh, '<', $file or die "Could not open file $file for reading: $!\n";
while ( my $line = <$fh> ) {
  ...
}

Sin embargo,al responder otra pregunta, Evan Carroll edité mi respuesta, cambiando miwhile declaración a:

while ( defined( my $line = <$fh> ) ) {
  ...
}

Su razón era que si tienes una línea que es0 (tendría que ser la última línea, de lo contrario tendría un retorno de carro) entonces suwhile saldría prematuramente si usaras mi declaración ($line se establecería en"0", y el valor de retorno de la asignación, por lo tanto, también sería"0" que se evalúa como falso). Si verifica la definición, entonces no se encuentra con este problema. Tiene mucho sentido

Entonces lo intenté. Creé un archivo de texto cuya última línea es0 sin retorno de carro. Lo pasé por mi bucle y el bucle no salió prematuramente.

Entonces pensé: "Ajá, tal vez el valor no es realmente0, tal vez hay algo más que está arruinando las cosas! "Así que solíaDump() deDevel::Peek y esto es lo que me dio:

SV = PV(0x635088) at 0x92f0e8
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0X962600 "0"\0
  CUR = 1
  LEN = 80

Eso parece decirme que el valor es en realidad la cadena"0", ya que obtengo un resultado similar si llamoDump() en un escalar que he establecido explícitamente en"0" (la única diferencia está en el campo LEN: desde el archivo LEN es 80, mientras que desde el escalar LEN es 8).

Entonces, ¿cuál es el trato? ¿Por qué mi nowhile() el bucle sale prematuramente si lo paso por una línea que solo es"0" sin retorno de carro? ¿El bucle de Evan es realmente más defensivo, o Perl hace algo loco internamente que significa que no necesita preocuparse por estas cosas ywhile() en realidad solo sale cuando golpeaseof?

Respuestas a la pregunta(3)

Su respuesta a la pregunta