Ключевое слово для эксклюзива или в рубине? - PullRequest
13 голосов
/ 25 февраля 2009

Есть ли в Ruby простое английское ключевое слово для эксклюзива или, как у них "и" и "или"? Если нет, то является ли это исключительным или не допускает краткую оценку?

Ответы [ 7 ]

20 голосов
/ 25 февраля 2009

Нет, нет, вы можете использовать только ^.

Не знаю, почему это не так, может быть, просто потому, что оно не так часто используется.

16 голосов
/ 29 июня 2009

Я столкнулся с проблемой, потому что оператор '^' действует побитово на числа,

true ^ 1
=> false

1 ^ true
TypeError: can't convert true into Integer
true ^ 1

так что мой обходной путь был:

( !!a ^ !!b ), где двойной взрыв приводит их к логическим значениям.

!!1 ^ !!true
=> false

!!1 ^ !!false
=> true
13 голосов
/ 25 февраля 2009

Во-первых, я не думаю, что короткое замыкание может быть разумно применимо к XOR: независимо от значения первого операнда, второй должен быть исследован.

Во-вторых, и, &&, или и || использовать короткое замыкание во всех случаях; единственная разница между версиями «слово» и «символ» - это приоритет. Я считаю, что and и or присутствуют для обеспечения той же функции, что и perl в строках, подобных

process_without_error or die

Я думаю, что причина отсутствия именованной функции xor, вероятно, заключается в том, что в этом случае нет никакого смысла в операторе с низким приоритетом, и это уже достаточно запутанная ситуация!

10 голосов
/ 25 февраля 2009

Попробуйте ^

true  ^ false #=> true
true  ^ true  #=> false
false ^ false #=> false

Нет простого английского эквивалентного оператора.

7 голосов
/ 15 июля 2014

В качестве альтернативы методу двойного отрицания Мэтта Ван Хорна для использования XOR на произвольных типах, вы можете связать другой тест XOR, начиная с nil. i.e.:

!!foo ^ !!bar

эквивалентно

nil ^ foo ^ bar

На мой взгляд, это выглядит аккуратно, и я полагаю, требуется еще одна менее логичная операция

2 голосов
/ 06 августа 2013

Ответ Джона кажется неверным. В irb с 1.9.3 xor ("cupcake", false) возвращает true, как и следовало ожидать.

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 
1 голос
/ 08 августа 2012

Любая реализация xor не допускает короткого замыкания. Оба выражения должны быть оценены независимо от того, что.

В Ruby есть оператор ^, но он будет подавлять истинные значения. Я реализовал функцию для обработки случаев, когда я хочу xor, который ведет себя больше как and и or:

def xor(a,b)
  (a and (not b)) or ((not a) and b)
end

В отличие от ^, эта функция может использоваться в ситуациях, подобных следующим:

xor("hello".match(/llo/), false) # => true
xor(nil, 1239)                   # => true
xor("cupcake", false)            # => false
...