Ruby ではをInteger === 5
返しますtrue
。同様にをString === "karthik"
返しますtrue
。
ただし、5 === Integer
返品しますfalse
。そして"karthik" === String
。
演算子が可換でないのはなぜですか?
4 に答える
簡単な答えは、意味がないからです。演算子が記述する関係は可換ではありません。なぜ演算子はそうでなければならないのですか?
あなた自身の例を見てください: 5
is an Integer
. しかしInteger
、5
ですか?それはどういう意味ですか?
===
は、場合の包含演算子であり、包含は交換されません。
ケースの包含演算子が等号を使用し、通常はトリプル イコールthreequals
またはcase equality
演算子と呼ばれるという事実は、等値とはまったく関係がないだけでなく、多くの法則にも準拠していないため、非常に残念です。等式は、推移性や交換性などに準拠しています。
についての私の怒りの詳細については、===
参照してください
非常に単純な理由の 1 つは、is_a?
クラスの関係が交換可能ではないということです。両方のオペランドがクラスである場合を考えてみましょう:
Class === String
これは true を返しますString.is_a?(Class)
。ただしString === Class
、 false を返します。これClass.is_a?(String)
は false であり、当然のことです。
もう 1 つの理由は、 のセマンティクスが===
左側のオペランドに依存することです。これにも 2 つの理由があります: a) ruby では、セマンティクスは常に左オペランドに依存します。なぜなら、左オペランドはメソッド呼び出しのレシーバーだからです。意図したセマンティクスを持つステートメント。
多くの演算子は可換ではありません。
は===
、分岐がケースである場合に呼び出されるため、「ケース等価演算子」と呼ばれます。
次のことが便利で便利です。
foo = 42
case foo
when Integer
# branches here
when String
# etc...
end
だったらあまり役に立たない
foo = Integer
case foo
when 42
# would branch here??
when 666
# etc...
end
Ruby 1.9 では、===
Proc/lambda の演算子はその Proc を呼び出すことに注意してください。
divisible_by_three = ->(x){x % 3 == 0}
divisible_by_three === 42 # => true
繰り返しますが、case
ステートメントでは非常に便利ですが、逆の順序ではあまり役に立ちません。
case-when比較を実装する必要があります
非可換演算子があるのは普通のことです。
/ - % [] . -> ^ << >> < <= > >= && || = += -= ,
そしてたまたま、部分的に case-when演算子===
として存在します。これは Ruby ではかなり手の込んだものであり、可換演算に単純化する必要がある場合、そうはなりません。