Assignment inside Perl ternary conditional operator problems

走远了吗. 提交于 2019-12-04 08:47:51

问题


This snippet of Perl code in my program is giving the wrong result.

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

No matter what the value of $condition is, the output is always 3, how come?


回答1:


This is explained in the Perl documentation.

Because of Perl operator precedence the statement is being parsed as

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

Because the ?: operator produces an assignable result, 3 is assigned to the result of the condition.

When $condition is true this means ($a=2)=3 giving $a=3

When $condition is false this means ($a)=3 giving $a=3

The correct way to write this is

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

We got bitten by this at work, so I am posting here hoping others will find it useful.




回答2:


Once you have an inkling that you might be suffering from precedence problems, a trick to figure out what Perl thought you meant:

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

In your case, that'll show you:

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

...at which point you should be saying "oh, that explains it"!




回答3:


Just to extend the previous answer... If, for whatever reason, the assignments need to be part of the conditional, you'd want to write it thusly:

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

This would be useful if you're assigning to different variables based on the condition.

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

And if you're choosing the variable, but assigning the same thing no matter what, you could even do this:

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



回答4:


Because of Perl operator precedence the statement is being parsed as:

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

Because the ?: operator produces an assignable result, 3 is assigned to the result of the condition.

When $condition is true this means $a=2=3 giving $a=3

When $condition is false this means $a=3 giving $a=3

The correct way to write this is

$a = $condition ? 2 : 3;

In general, you should really get out of the habit of using conditionals to do assignment, as in the original example -- it's the sort of thing that leads to Perl getting a reputation for being write-only.

A good rule of thumb is that conditionals are only for simple values, never expressions with side effects. When you or someone else needs to read this code eight months from now, would you prefer it to read like this?

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

Or like this?

if ($x < 3) {
  $foo($x);
} else {
  $bar($y);
}



回答5:


One suggestion to Tithonium's answer above:

If you are want to assign different values to the same variable, this might be better (the copy-book way):

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



来源:https://stackoverflow.com/questions/9009/assignment-inside-perl-ternary-conditional-operator-problems

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!