Ruby には、"and" や "or" があるように、排他的な or を表す平易な英語のキーワードはありますか? そうでない場合、これは排他的または評価のショートカットが許可されていないためですか?
7 に答える
いいえ、使用できません^
。
特にない理由はわかりませんが、一般的に使用されていないためかもしれません。
'^'演算子が数値に対してビット単位で動作するため、問題が発生しました。
true ^ 1
=> false
1 ^ true
TypeError: can't convert true into Integer
true ^ 1
だから私の回避策は:
( !!a ^ !!b )
ダブルバンがそれらをブール値に強制します。
!!1 ^ !!true
=> false
!!1 ^ !!false
=> true
まず、ショートサーキットを XOR に適切に適用できるとは思いません。最初のオペランドの値がどうであれ、2 番目のオペランドを調べる必要があります。
次に、and、&&、または and || すべての場合に短絡を使用してください。「単語」バージョンと「シンボル」バージョンの唯一の違いは優先順位です。とは、perl が次のような行で持っているのと同じ機能を提供するために存在するand
と私は信じていますor
process_without_error or die
名前付き関数がない理由xor
は、おそらく、この場合優先度の低い演算子には意味がなく、すでに十分に混乱している状況だからだと思います!
試す^
true ^ false #=> true
true ^ true #=> false
false ^ false #=> false
ただし、プレーンな英語の同等の演算子はありません。
任意の型で XOR を使用するための Matt Van Horn の二重否定トリックの代わりに、 で始まる別の XOR テストを連鎖させることができますnil
。すなわち:
!!foo ^ !!bar
と同等です
nil ^ foo ^ bar
これは私の目にはきれいに見えます。論理演算が1つ少なくて済むと思います
ジョンの答えは間違っているようです。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
の実装でxor
は、短絡は許可されません。どちらの式も評価する必要があります。
Ruby は^
演算子を提供しますが、これは真の値で窒息します。andxor
のように動作する が必要な場合を処理する関数を実装しました。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