2009-10-29 20 views
3

J'ai essayé cet exemple en Perl. Quelqu'un peut-il expliquer pourquoi est-ce vrai? Il imprime true.Pourquoi sdf défini retourne-t-il true dans cet exemple Perl?

sdf peut être n'importe quel nom.

En outre, si la fonction sdf est définie et qu'elle renvoie 0, elle n'imprime rien.

print (sdf); n'imprime pas la chaîne sdf mais

if (sdf eq "sdf") 
{ 
print "true"; 
} 

imprime vrai. La question connexe demeure si sdf est une chaîne. Qu'est-ce qui n'est pas imprimé par impression?

+0

@Aftershock: J'ai mis à jour ma réponse pour répondre au dernier problème que vous avez soulevé. –

Répondre

10

sdf est un bareword.

perl -Mstrict -e "print qq{defined\n} if defined sdf" 
 
Bareword "sdf" not allowed while "strict subs" in use at -e line 1. 
Execution of -e aborted due to compilation errors. 

Pour plus de plaisir, essayez

perl -Mstrict -e "print sdf => qq{\n}" 

Voir Strictly speaking about use strict:

Les sous-marins aspect de l'utilisation stricte désactive l'interprétation des `` mots nus '' comme des chaînes de texte . Par défaut, un identificateur Perl (une séquence de lettres, de chiffres et de traits de soulignement ne commençant pas par un chiffre sauf s'il est entièrement numérique) qui n'est pas un mot clé intégré ou une définition de sous-routine précédemment vue est traité comme une chaîne de texte

@daynames = (sun, mon, tue, wed, thu, fri, sat); 

Cependant, cela est considéré comme une pratique dangereuse, parce que les bugs obscurs peuvent entraîner:

@monthnames = (jan, feb, mar, apr, may, jun, 
       jul, aug, sep, oct, nov, dec); 

Pouvez-vous repérer le bug? Oui, la 10ème entrée n'est pas la chaîne 'oct', mais plutôt une invocation de la fonction oct() intégrée, renvoyant l'équivalent numérique du $_ par défaut traité comme un nombre octal.

Correction: (@ysth thanks)

 
E:\Home> perl -we "print sdf" 
Unquoted string "sdf" may clash with future reserved word at -e line 1. 
Name "main::sdf" used only once: possible typo at -e line 1. 
print() on unopened filehandle sdf at -e line 1. 

Si un bareword est fourni à print dans la fente d'objet indirect, il est pris comme descripteur de fichier à imprimer. Comme aucun autre argument n'est fourni, print utilise par défaut $_ pour gérer le fichier sdf. Puisque sdf n'a pas été ouvert, il échoue. Si vous exécutez ceci sans avertissements, vous ne voyez aucune sortie. Notez également:

 
E:\Home> perl -MO=Deparse -e "print sdf" 
print sdf $_; 

comme confirmation de cette observation. A noter également:

 
E:\Home> perl -e "print asdfg, sadjkfsh" 
No comma allowed after filehandle at -e line 1. 
 
E:\Home> perl -e "print asdfg => sadjkfsh" 
asdfgsadjkfsh 

Ce dernier imprime les deux chaînes parce que => cite automatiquement les chaînes sur la LHS si elles sont composées uniquement de caractères « mot », en supprimant l'interprétation du filehandle premier argument.

Tous ces exemples montrent que l'utilisation de barewords entraîne de nombreuses surprises. Vous devriez use strict pour éviter de tels cas.

3

defined renvoie true si l'expression a une valeur autre que la valeur indéfinie.

+0

A-t-il une valeur? Imprimer sdf ne montre rien ... – Aftershock

+2

@Sinan Ünür: parce que l'impression prend un objet indirect, pas parce que l'appel d'impression fournit un contexte de liste. – ysth

+0

@ysth noté. J'ai édité ma réponse pour refléter votre correction. –

4

L'exemple n'est pas spécial:

telemachus ~ $ perl -e 'if (defined sdf) { print "True\n" };' 
True 
telemachus ~ $ perl -e 'if (defined abc) { print "True\n" };' 
True 
telemachus ~ $ perl -e 'if (defined ccc) { print "True\n" };' 
True 
telemachus ~ $ perl -e 'if (defined 8) { print "True\n" };' 
True 

Aucune de celles-ci est équivalent à undef qui est ce que defined chèques pour.

Vous pouvez consulter cet article sur la vérité en Perl: What is Truth?

+1

Votre dernier exemple, '8', est différent des autres de manière cruciale. –

+2

@Sinan: Yup, c'est un numéro. Expliquer que 'sdf' est un mot simple est utile, mais je me suis concentré sur le fait de dire qu'il n'y avait rien de magique à propos de' sdf'. – Telemachus

+0

@Sinan: merci pour cela. J'ai toujours pensé que la chaîne vide * était * indéfinie. C'est mon erreur, et je vais le corriger. – Telemachus

5

Ceci est un "bareword". Si cela est autorisé, il a la valeur "sdf" et n'est donc pas indéfini.

+0

En fait, '0' est' false' mais 'defined'. Vérifiez-le: 'perl -e 'if (défini 0) {print" True \ n "};'' – Telemachus

+0

Désolé, vous avez absolument raison. :-) Maintenant corrigé. – Tim

0

La fonction définie renvoie true à moins que la valeur transmise dans l'argument ne soit indéfinie. Ceci est utile en distinguant une variable contenant 0 ou "" d'une variable qui vient de clignoter.