Comment le comportement différent de la unless- et la déclaration « si! » Influence la gamme opérateur dans un contexte scalaire?
-
25-09-2019 - |
Question
http://novosial.org/perl/one-liner/ I trouvé les deux one-liners suivants. Les sorties sont différentes car l'instruction unless
est différente de if !
(en raison des règles et leur priorité).
cat file: foo bar
perl -ne 'print unless /^$/../^$/' file foo bar
perl -ne 'print if ! /^$/../^$/' file foo bar
Comment le comportement différent de la if !
-déclaration fait la deuxième sortie en une ligne une ligne vide?
La solution
Comme l'article lié dit, il est une question de priorité et ... associativité
print unless /^$/../^$/
est équivalente à print if !(/^$/../^$/)
print if ! /^$/../^$/
est équivalente à print if (!/^$/)../^$/
Notez que la première expression de l'annule gamme, tandis que la seconde annule la condition de début de la plage, mais pas la plage elle-même.
Autres conseils
La réponse, à mon humble avis, est qu'il n'y a pas de déclaration if !
en Perl: Il y a une déclaration if
et il y a un opérateur !
. L'opérateur !
ne se lie pas à if
; il fonctionne sur son argument. Si vous commencez à penser en ces termes, votre vie sera plus facile.
Alors, 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
de sorte que la valeur de vérité de cette condition est équivalente à la vérité de something
, mais ont omis de prendre en compte le fait que l'opérateur de !
se lie étroitement.
Voilà pourquoi il y a not
.
Essayez
perl -ne 'print if not /^$/../^$/' file
Voir not
dans perldoc perlop :
unaire
not
renvoie la négation logique de l'expression à sa droite. Il est l'équivalent de!
, sauf pour la priorité très faible.
Le test de gamme retourne vrai jusqu'au moment que le 2ème opérande est vrai. Il retourne alors faux sur le prochain appel.
Cet extrait nous dit ce que l'opérateur de la plage est de retour
perl -ne "$x= ( ! /^$/../^$/ ) ; print qq/$x : $_/" range_test.TXT
qui produit
1 : foo
2E0 :
:
:
1 : bar
La première ligne vide génère une vraie réponse, la suivante false