Zuweisung innerhalb von ternären bedingten Operatorproblemen in Perl
-
08-06-2019 - |
Frage
Dieser Perl-Codeausschnitt in meinem Programm liefert das falsche Ergebnis.
$condition ? $a = 2 : $a = 3 ;
print $a;
Egal welchen Wert es hat $condition
ist, die Ausgabe ist immer 3, wie kommt es?
Lösung
Dies wird im Perl erklärt Dokumentation.
Aufgrund der Perl-Operatorpriorität wird die Anweisung als geparst
($condition ? $a= 2 : $a ) = 3 ;
Weil das ?:Der Operator erzeugt ein zuweisbares Ergebnis, 3 wird dem Ergebnis der Bedingung zugewiesen.
Wenn $condition wahr ist, bedeutet dies ($a=2)=3, was $a=3 ergibt
Wenn $condition falsch ist, bedeutet dies ($a)=3, was $a=3 ergibt
Die richtige Art, dies zu schreiben, ist
$a = ( $condition ? 2 : 3 );
print $a;
Da wir bei der Arbeit davon betroffen waren, poste ich es hier in der Hoffnung, dass andere es nützlich finden.
Andere Tipps
Sobald Sie eine Ahnung haben, dass Sie unter Prioritätsproblemen leiden könnten, gibt es einen Trick, um herauszufinden, was Perl meinte:
perl -MO=Deparse,-p -e '$condition ? $a= 2 : $a= 3 ; print $a;'
In Ihrem Fall zeigt Ihnen das Folgendes:
(($condition ? ($a = 2) : $a) = 3);
print($a);
-e syntax OK
...an diesem Punkt sollten Sie sagen: "Oh, das erklärt es"!
Nur um die vorherige Antwort zu erweitern ...Wenn die Aufgaben aus irgendeinem Grund Teil der Bedingung sein müssen, sollten Sie sie folgendermaßen schreiben:
$condition ? ($a=2) : ($a=3);
Dies wäre nützlich, wenn Sie je nach Bedingung unterschiedliche Variablen zuweisen.
$condition ? ($a=2) : ($b=3);
Und wenn Sie die Variable auswählen, aber auf jeden Fall dasselbe zuweisen, könnten Sie sogar Folgendes tun:
($condition ? $a : $b) = 3;
Aufgrund der Perl-Operatorpriorität wird die Anweisung wie folgt analysiert:
($condition ? $a = 2 : $a ) = 3 ;
Weil das ?:Der Operator erzeugt ein zuweisbares Ergebnis, 3 wird dem Ergebnis der Bedingung zugewiesen.
Wenn $condition wahr ist, bedeutet dies, dass $a=2=3 $a=3 ergibt
Wenn $condition falsch ist, bedeutet dies, dass $a=3 $a=3 ergibt
Die richtige Art, dies zu schreiben, ist
$a = $condition ? 2 : 3;
Im Allgemeinen sollten Sie sich wirklich nicht mehr angewöhnen, für Zuweisungen Bedingungen zu verwenden, wie im ursprünglichen Beispiel – das ist die Art von Dingen, die dazu führen, dass Perl den Ruf bekommt, nur schreibgeschützt zu sein.
Eine gute Faustregel ist, dass Bedingungen nur für einfache Werte gelten, niemals für Ausdrücke mit Nebenwirkungen.Wenn Sie oder jemand anderes diesen Code in acht Monaten lesen muss, wäre es Ihnen dann lieber, wenn er so wäre?
$x < 3 ? foo($x) : bar($y);
Oder so?
if ($x < 3) {
$foo($x);
} else {
$bar($y);
}
Ein Vorschlag zu Tithoniums Antwort oben:
Wenn Sie derselben Variablen unterschiedliche Werte zuweisen möchten, ist dies möglicherweise besser (auf die Copy-Book-Methode):
$a = ($condition) ?2:3;