views:

46

answers:

2

After writing my response on the question how to assign to multiple variables in a ternary operator I actually tried out the code I wrote:

true ? $w = 100 xor $r = 200 : $w = 300 xor $r = 400;
var_dump($w); var_dump($r);

(Don't bother it's useless, this is theoretic.)

Now, I would expect PHP to do it this way, according to operator precedence:

 true  ?   $w = 100  xor  $r = 200   :   $w = 300  xor  $r = 400  ;
(true) ? ( $w = 100  xor  $r = 200 ) : ( $w = 300  xor  $r = 400 );
(true) ? (($w = 100) xor ($r = 200)) : (($w = 300) xor ($r = 400));

As the first part of the ternary operator is evaluated, this should output:

int 100
int 200

But instead I get

int 100
int 400

This is very odd to me, because it would require that parts of both parts of the ternary operator are executed.

Suppose it's some stupid fault in my thinking...

+4  A: 

aren't you just doing

(true ? $w = 100 xor $r = 200 : $w = 300) xor $r = 400;
mvds
Just like the one-command for loop without braces that someone tags a second command onto, and finds out it's only done once at the end. Oops.
Nerdling
This makes sense, I think PHP is putting that last xor outside of the operator. Like with calculators, you **need to include parentheses around everything**.
animuson
followed your link to php.net and it's just there, `xor` precedence is lower than `?:` QED.
mvds
what I like best is macros in C with too little parentheses, like `#define AVERAGE(x,y) x/2+y/2` and then evaluating `AVERAGE(10,1)*2`. oh the joy. even better when using lowercase, so the macro hint isn't even there.
mvds
damn it, you're perfectly right. I'm always trapped by the ternary. @C: Yeah, I know that. But with C it's somehow practice to surround the macro and all variables with parentheses. In PHP I'm used to not using them. Backfires sometimes...
nikic
this reminds me of this *(c++) precedence question... even getting all parentheses right: `#define SQUARE(x) ((x)*(x))`, predict output of `int c=2;printf("%d\n",SQUARE(++c));`
mvds
Translating the makro: `c=2;printf("%d\n",((++c)*(++c)));` And this is: `c=2;printf("%d\n",3*4);`. So it outputs `12`, does it?
nikic
return(-EAGAIN)
mvds
+1  A: 

I wouldn't use the ternary operator in this way at all. Use the ternary operator when you need the whole expression to return a value, not as a substitute for logical code constructs.

For example:

if (true) {
  $w = 100;
  $r = 200;
} else {
  $w = 300;
  $r = 400;
}

var_dump($w); 
var_dump($r);

Advantages of using if/else construct:

  • Easier to read, easier to maintain, easier to debug.
  • Easier to add more steps inside each conditional block if the need arises.
  • If you run tests using code coverage tools, you get a more accurate view of which code paths are being tested when all your code isn't on one line.
  • You don't have to post a question to Stack Overflow to get it working!

Advantages of using ternary operator:

  • Uses fewer curly-braces and semicolons, in case you're running out of them or can't find them on your keyboard.
Bill Karwin
Yeah, I would never even think of using this. The question was purely theoretical ;) But hay, you said it: On my German Keybord I have to Press `Alt Gr + 7` to open a curly brace... Quite complicated, isn't it?
nikic
Point taken. In many national keyboard layouts, `Alt Gr` is required to get access to curly braces and other characters common in programming languages.
Bill Karwin