2010-03-07 23 views
3

Sur http://novosial.org/perl/one-liner/ J'ai trouvé les deux lignes suivantes. Les sorties sont différentes car l'instruction unless est différente de if ! (en raison des règles d'associativité et de précédence).Comment le comportement différent de la "et si" et "si!" instruction influence l'opérateur de plage dans un contexte scalaire?

 
cat file: 
foo 



bar 
 
perl -ne 'print unless /^$/../^$/' file 
foo 
bar 
 
perl -ne 'print if ! /^$/../^$/' file 
foo 

bar 

Comment le comportement différent du if ! -Déclaration faire la deuxième sortie en une ligne d'une ligne blanche?

Répondre

6

Comme l'article lié dit, il est une question de et leur priorité ...

print unless /^$/../^$/ est équivalent à print if !(/^$/../^$/)

print if ! /^$/../^$/ équivaut à print if (!/^$/)../^$/

Notez que la première nie l'expression de gamme , tandis que le second annule la condition de début de la plage, mais pas la plage elle-même.

1

Le test de plage retournera vrai jusqu'à ce que le deuxième opérande soit vrai. Il retournera alors faux sur l'appel suivant.

Cet extrait nous dit ce que l'opérateur de gamme revient

qui produit

1 : foo 
2E0 : 
: 
: 
1 : bar 

Ainsi, la première ligne vide génère une réponse vraie, le prochain faux

4

La réponse , À mon humble avis, est qu'il n'y a pas d'instruction if ! en Perl: Il y a une déclaration if et il y a un opérateur ! . L'opérateur ! ne lie pas à if; il opère sur son argument. Si vous commencez à penser en ces termes, votre vie sera plus facile.

Ainsi, dans votre cas, vous avez,

do_something() unless something; 

et

do_something() if something-else; 

Mettons entre parenthèses normalement invisibles:

do_something() unless (something); 

et

do_something() if (something-else); 

Dans ce cas, vous avez essayé d'écrire something-else afin que la valeur de vérité de cette condition soit équivalente à la vérité de something, mais n'a pas pris en compte le fait que l'opérateur ! se lie étroitement.

C'est pourquoi il existe not.

Essayez

perl -ne 'print if not /^$/../^$/' file 

Voir not in perldoc perlop:

unaire not renvoie la négation logique de l'expression à sa droite. C'est l'équivalent de ! à l'exception de la très faible priorité.