はじめに
==
/ ===
/ equal?
/ eql?
は別物のようです。
==
:値が等しいかを返す
p "foo" == "foo" #=> true
p 4 == 4 #=> true
p 4 == 4.0 #=> true
===
:値を含むかを返す
厳密には誤った用法かもしれませんが、大枠は「含む」イメージで正しいと思います。
Rubyリファレンスマニュアル
以下のように説明されています。
case 式で使用されるメソッドです。
このメソッドは case 式での振る舞いを考慮して、各クラスの性質に合わせて再定義すべきです。
デフォルトでは内部で Object#== を呼び出します。
Range#=== は主に case 式での比較に用いられます。
# 左辺クラスのインスタンスであるかを返す
p String === "foo" #=> true
# 左辺範囲オブジェクトに含まれているかを返す
p (1..5) === 4 #=> true
p (1..5) === 4.0 #=> true
# == と同じ
p "foo" === "foo" #=> true
p 4 === 4 #=> true
p 4 === 4.0 #=> true
equal?
:object_id
が一致するかを返す
Rubyリファレンスマニュアル
p "foo".equal?("foo") #=> false
p :foo.equal?(:foo) #=> true
p 4.equal?(4) #=> true
p 4.equal?(4.0) #=> false
eql?
Rubyリファレンスマニュアル
p "foo".eql?("foo") #=> true
p :foo.eql?(:foo) #=> true
p 4.eql?(4) #=> true
p 4.0.eql?(4) #=> false
比較対象は==
だと思います。
==
:1 == 1.0 => true
eql?
:1.eql?(4.0) => false
eql?
は、同値であっても型が違うとfalse
を返します。
余談:JavaScriptとの違い
JavaScriptでは、==
/ ===
は以下の意味を持ちます。
-
==
:ゆるい等価性 -
===
:厳密な等価性
console.log(1 == "1") //true
console.log(1 === "1") //false
そのため、基本的には===
を使います。
おわりに
Rubyは「別の名前だけど同じ挙動」というメソッドが多いです。
(length
とsize
・reduce
とinject
など)
今回は、それぞれが「似た名前だけど別の挙動」でしたね。
以上、等価性にまつわるメソッドについてでした。