Asignarea în interiorul Perl problemelor operatorului condițional ternar

Acest fragment de cod Perl din programul meu dă rezultate greșite.

$condition ? $a = 2 : $a = 3 ;
print $a;

Indiferent de valoarea $ condition , ieșirea este întotdeauna 3, cum se întâmplă?

0
fr hi bn

5 răspunsuri

Acest lucru este explicat în Perl documentație .

Din cauza precedentului operatorului Perl, instrucțiunea este analizată ca

($condition ? $a= 2 : $a ) = 3 ;

Deoarece operatorul ?: produce un rezultat asignabil, 3 este atribuit rezultatului condiției.

Când condiția $ este adevărată, înseamnă că ($ a = 2) = 3 dând $ a = 3

Când condiția $ este falsă, înseamnă că ($ a) = 3 dând $ a = 3

Modul corect de a scrie acest lucru este

$a = ( $condition ? 2 : 3 );
print $a;

Am fost mușcați de asta la locul de muncă, deci postez aici sperând că alții o vor găsi utile.

0
adăugat
Aveți dreptate că o voi modifica ($ a = 2) = 3 în loc de $ a = 2 = 3
adăugat autor Pat, sursa
"Când condiția $ este adevărată înseamnă că $ a = 2 = 3 dând $ a = 3" aș fi crezut că $ a = 2 = 3 ar fi o eroare de sintaxă expresie sau o eroare cerută de lvalue sau ... Cum se obține evaluat?
adăugat autor sundar, sursa

O sugestie pentru răspunsul lui Tithonium de mai sus:

Dacă doriți să atribuiți diferite valori aceleiași variabile, aceasta ar putea fi mai bună (modul de copiere):

$ a = (condiție $)? 2: 3;

0
adăugat

Doar pentru a extinde raspunsul anterior ... Daca, indiferent de motiv, misiunile trebuie sa fie parte din conditional, ar trebui sa il scrieti astfel:

$condition ? ($a=2) : ($a=3);

Acest lucru ar fi util dacă alocați variabilelor diferite bazate pe această condiție.

$condition ? ($a=2) : ($b=3);

Și dacă alegeți variabila, dar atribuind același lucru indiferent de ce, puteți face chiar și acest lucru:

($condition ? $a : $b) = 3;
0
adăugat

Odată ce ai o îndoială că s-ar putea să suferi de probleme de prioritate, un truc să-ți dai seama ce crede că ai vrut să spui:

perl -MO=Deparse,-p -e '$condition ? $a= 2 : $a= 3 ; print $a;'

În cazul tău, asta îți va arăta:

(($condition ? ($a = 2) : $a) = 3);
print($a);
-e syntax OK

... la ce punct ar trebui să spui "oh, asta explică"!

0
adăugat
Deparse este un truc de partid foarte curat. Desigur, odată ce bănuiți o problemă de prioritate, sunteți, de obicei, cea mai mare parte a drumului spre soluție ;-)
adăugat autor RET, sursa

Din cauza precedentului operatorului Perl, instrucțiunea este analizată ca fiind:

($condition ? $a = 2 : $a ) = 3 ;

Deoarece operatorul ?: produce un rezultat asignabil, 3 este atribuit rezultatului condiției.

Când condiția $ este adevărată, înseamnă că $ a = 2 = 3 dând $ a = 3

Când $ condiție este falsă acest lucru înseamnă $ a = $ 3, care a = 3

Modul corect de a scrie acest lucru este

$a = $condition ? 2 : 3;

În general, ar trebui să renunți la obișnuința de a folosi condiționate pentru a face o sarcină, ca în exemplul original - este un fel de lucru care duce la Perl obținerea unei reputații pentru a fi scris numai.

O regulă bună este că condiționările sunt doar pentru valori simple, niciodată expresii cu efecte secundare. Când tu sau altcineva trebuie să citești acest cod de opt luni de acum, ai prefera să citești așa?

$x < 3 ? foo($x) : bar($y);

Sau așa?

if ($x < 3) {
  $foo($x);
} else {
  $bar($y);
}
0
adăugat