Does Ruby have a plain-English keyword for exclusive or, like they have "and" and "or"? If not, is this because exclusive or doesn't allow evaluation short-cutting?
Firstly, I don't think shortcircuiting can sensibly apply to XOR: whatever the value of the first operand, the second needs to be examined.
Secondly, and, &&, or and || use shortcircuiting in all cases; the only difference between the "word" and "symbol" versions is precedence. I believe that and
and or
are present to provide the same function as perl has in lines like
process_without_error or die
I think the reason for not having a xor
named function is probably that there's no point in a low-precedence operator in this case and that it's already a confusing enough situation!
No it doesn't, you can only use ^
.
Don't know why there isn't particularly, may just be because it isn't as commonly used.
I ran into an issue because the '^' operator acts bitwise on numbers,
true ^ 1
=> false
1 ^ true
TypeError: can't convert true into Integer
true ^ 1
so my workaround was:
( !!a ^ !!b )
where the double-bang coerces them into booleans.
!!1 ^ !!true
=> false
!!1 ^ !!false
=> true
Try ^
true ^ false #=> true
true ^ true #=> false
false ^ false #=> false
No plain english equivalent operator though.
As an alternative to Matt Van Horn's double negation trick for using XOR on arbitrary types, you can chain another XOR test, starting with nil
. i.e.:
!!foo ^ !!bar
is equivalent to
nil ^ foo ^ bar
This looks neater to my eye, and I suppose requires one less logical operation
Any implementation of xor
won't allow short circuiting. Both expressions need to be evaluated no matter what.
Ruby does provide the ^
operator, but this will choke on truthy values. I've implemented a function to handle the cases where I want an xor
that behaves more like and
and or
:
def xor(a,b)
(a and (not b)) or ((not a) and b)
end
Unlike ^
, this function can be used in situations similar to the following:
xor("hello".match(/llo/), false) # => true
xor(nil, 1239) # => true
xor("cupcake", false) # => false
John's answer appears incorrect. In irb with 1.9.3, xor("cupcake", false) returns true, as you'd expect.
1.9.3-p429 :104 > def xor(a,b)
1.9.3-p429 :105?> (a and (not b)) or ((not a) and b)
1.9.3-p429 :106?> end
=> nil
1.9.3-p429 :107 > xor(false, true)
=> true
1.9.3-p429 :108 > xor("cupcake", false)
=> true
来源:https://stackoverflow.com/questions/585195/keyword-for-exclusive-or-in-ruby