Can someone please explain what’s going on here, please?
I’ve simplified as much as I can.
( 1 || 2 == 1 ) is TRUE (as expected)
( 1 || 2 == 2 ) is TRUE (as expected)
I would also expect the following to both be true (but this may suggest a lack of understanding…)
( 1 == ( 1 || 2 ) ) is TRUE
( 2 == ( 1 || 2 ) ) is FALSE <--- !!! I don't understand this..
Now it starts getting a bit odd…
( 2 == 1 || 2 ) is TRUE
( 3 == 1 || 2 ) is TRUE <--- !!! I don't understand this..
After some more playing about, I find the following:
( 1 == ( 1 || 2 ) ) is FALSE
( 2 == ( 1 || 2 ) ) is TRUE
( 1 == ( 1 && 2 ) ) is TRUE
( 2 == ( 1 && 2 ) ) is FALSE
You might have guess that I’m trying to do something along the lines of:
sub foo {
# ... blah blah ...
return 0 if $status == ( 2 || 4 || 7 || 9);
# ... do other stuff ...
return 1;
}
my $result = foo();
if ($result) {
# then do something based on a result
} else {
# log failure or whatever
}
I know I can use this idiom, but the extra “$status”(es) seem superfluous:
return 0 if ( $status == 1 || $status == 4 || $status == 7 ); # and so on...
I also know I could use a regex with alternation or to check if the value is in an array of the allowable values.
But I’d like to understand why this is not as I expect.
will not do what you expect. (And if it did do what you expect, what do you think
$status == (2 && 4 && 7 && 9)should mean?) That statement is equivalent to||and&&are binary operators that always return one of their scalar operands. It may help to think of them as equivalent to these binary functions:(I’m glossing over the short-circuiting feature of
||and&&, but that’s not so important for this post).Noting that
==has higher precedence than||and&&, we can rewrite all your expressions in terms ofANDandOR:These two expressions are both true, but NOT for the reason you were expecting.
And your original idea of checking
is equivalent to