I boucle généralement par des lignes dans un fichier en utilisant le code suivant:Quel est le moyen le plus défensif de faire défiler des lignes dans un fichier avec Perl?
open my $fh, '<', $file or die "Could not open file $file for reading: $!\n";
while (my $line = <$fh>) {
...
}
Cependant, in answering another question, Evan Carroll modifié ma réponse, en changeant ma déclaration while
à:
while (defined(my $line = <$fh>)) {
...
}
Son raisonnement était que si vous avoir une ligne qui est 0
(il devrait être la dernière ligne, sinon il aurait un retour chariot) alors votre while
quitterait prématurément si vous avez utilisé ma déclaration ($line
serait réglé sur "0"
, et la valeur de retour de l'affectation serait donc également "0"
qui sera évaluée à faux). Si vous vérifiez pour défini-ness, alors vous ne rencontrez pas ce problème. Cela prend tout son sens.
Alors je l'ai essayé. J'ai créé un fichier texte dont la dernière ligne est 0
sans retour chariot. Je l'ai couru dans ma boucle et la boucle ne s'est pas éteinte prématurément. Je pensais alors, "Aha, peut-être que la valeur n'est pas vraiment 0
, peut-être y a-t-il quelque chose d'autre qui fout le pot!" Donc, je Dump()
de Devel::Peek
et voici ce qu'il m'a donné:
SV = PV(0x635088) at 0x92f0e8
REFCNT = 1
FLAGS = (PADMY,POK,pPOK)
PV = 0X962600 "0"\0
CUR = 1
LEN = 80
Cela me semble dire que la valeur est en fait la chaîne "0"
, que je reçois un résultat similaire si je l'appelle Dump()
sur un scalaire I » ve explicitement mis à "0"
(la seule différence est dans le champ LEN - du fichier LEN est 80, alors que de la LEN scalaire est 8).
Alors, quel est le problème? Pourquoi ma boucle while()
ne quitte-t-elle pas prématurément si je lui passe une ligne "0"
sans retour chariot? La boucle d'Evan est-elle réellement plus défensive, ou est-ce que Perl fait quelque chose de fou en interne, ce qui signifie que vous n'avez pas besoin de vous inquiéter de ces choses et que while()
sort seulement quand vous frappez eof
?
Si vous cherchez à écrire du code défensif, utilisez un [tank] (http://en.wikipedia.org/wiki/Tank). –
C'est pourquoi je ne modifierais pas le sens de la réponse de quelqu'un (je corrige uniquement les fautes de frappe évidentes). Ajoutez un commentaire à la place si vous pensez que quelque chose manque ou pourrait être amélioré. Et bravo à vous pour enquêter sur les internes! – Ether