Keyword for exclusive or in ruby?

旧城冷巷雨未停 提交于 2019-11-30 17:27:37

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
ChrisPhoenix

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