Was ist der defensivste Weg, um mit Perl durch Zeilen in einer Datei zu schleifen?

Ich durchlaufe normalerweise Zeilen in einer Datei mit dem folgenden Code:

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

Jedoch,in Beantwortung einer anderen Frage, Evan Carroll bearbeitete meine Antwort und änderte meinwhile Anweisung an:

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

Seine Begründung war, dass, wenn Sie eine Linie haben, die @ i0 (es müsste die letzte Zeile sein, sonst hätte es einen Wagenrücklauf) dann deinwhile würde vorzeitig beendet, wenn Sie meine Anweisung $line würde auf @ geset"0", und der Rückgabewert aus der Zuordnung wäre somit auch"0", das mit false bewertet wird). Wenn Sie auf Definiertheit prüfen, tritt dieses Problem nicht auf. Es macht vollkommen Sinn.

So habe ich es versucht. Ich habe eine Textdatei erstellt, deren letzte Zeile @ is0 ohne Wagenrücklauf. Ich habe meine Schleife durchlaufen und die Schleife wurde nicht vorzeitig beendet.

Ich dachte dann: "Aha, vielleicht ist der Wert nicht wirklich0, vielleicht gibt es da noch etwas, was die Dinge vermasselt! "Also habe ich @ benutDump() vonDevel::Peek und das hat es mir gegeben:

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

Das scheint mir zu sagen, dass der Wert tatsächlich die Zeichenfolge ist"0", da ich ein ähnliches Ergebnis erhalte, wenn ich @ anruDump() auf einem Skalar, den ich explizit auf @ gesetzt ha"0" (der einzige Unterschied besteht im LEN-Feld - aus der Datei LEN ist 80, aus der skalaren LEN ist 8).

Also, was ist der Deal? Warum funktioniert mein @ nicwhile() Schleife vorzeitig beenden, wenn ich eine Zeile übergebe, die nur @ i"0" ohne Wagenrücklauf? Ist Evans Loop tatsächlich defensiver oder macht Perl intern etwas Verrücktes, was bedeutet, dass Sie sich über diese Dinge keine Sorgen machen müssen undwhile() wird eigentlich nur beendet, wenn Sie @ drückeof?

Antworten auf die Frage(6)

Ihre Antwort auf die Frage