Wie funktioniert das unterschiedliche Verhalten der unless- und „wenn“ den Entfernungs-Operator in Skalarkontext beeinflusst Aussage?

StackOverflow https://stackoverflow.com/questions/2395808

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?

War es hilfreich?

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top