Wie funktioniert das unterschiedliche Verhalten der unless- und „wenn“ den Entfernungs-Operator in Skalarkontext beeinflusst Aussage?
-
25-09-2019 - |
Frage
http://novosial.org/perl/one-liner/ I die folgenden zwei Einzeiler gefunden. Die Ausgänge sind unterschiedlich, weil die unless
Aussage unterscheidet sich von if !
ist (aufgrund der Assoziativität und Vorrangregeln).
cat file: foo bar
perl -ne 'print unless /^$/../^$/' file foo bar
perl -ne 'print if ! /^$/../^$/' file foo bar
Wie funktioniert das unterschiedliche Verhalten der if !
-Aussage macht den zweiten Einzeiler Ausgang eine Leerzeile?
Lösung
Wie der verlinkten Artikel sagt, es ist eine Frage der Assoziativität und Vorrang ...
print unless /^$/../^$/
entspricht print if !(/^$/../^$/)
print if ! /^$/../^$/
entspricht print if (!/^$/)../^$/
Beachten Sie, dass die ersten negiert den Bereich Ausdruck, während die zweite negiert die Anfangszustand des Bereichs, aber nicht der Bereich selbst.
Andere Tipps
Die Antwort, IMHO, ist, dass es keine if !
Anweisung in Perl: Es gibt eine if
Aussage und es gibt einen !
Operator. Der !
Betreiber nicht zu if
binden; es arbeitet auf ihr Argument. Wenn Sie in diesen Begriffen anfangen zu denken, wird Ihr Leben einfacher sein.
Also, in Ihrem Fall, Sie haben,
do_something() unless something;
und
do_something() if something-else;
Sagen wir in den normalerweise unsichtbaren Klammern:
do_something() unless ( something );
und
do_something() if ( something-else );
In diesem Fall versucht, Sie zu schreiben something-else
so dass der Wahrheitswert dieser Bedingung für die Wahrheit something
äquivalent ist, aber nicht zu berücksichtigen, dass !
Operator bindet fest.
Das ist, warum es not
ist.
Versuchen
perl -ne 'print if not /^$/../^$/' file
Siehe not
in perldoc perlop :
Unary
not
gibt die logische Negation des Ausdrucks zu ihrem Recht. Es ist das Äquivalent von!
mit Ausnahme des sehr niedrigen Rang.
Der Bereich Test wird return true bis zu dem Zeitpunkt, dass der zweite Operand wahr ist. Es wird dann falsch auf den nächsten Anruf zurück.
Dieser Code-Schnipsel sagt uns, was der Bereich Operator zurückkehrt
perl -ne "$x= ( ! /^$/../^$/ ) ; print qq/$x : $_/" range_test.TXT
, die erzeugt
1 : foo
2E0 :
:
:
1 : bar
So ist die erste leere Zeile erzeugt eine wahre Antwort, die nächste false