💭
【Ruby】equal?, eql?, ==, === の違い
TL;DR
-
equal?
:object_id
の比較 -
eql?
: 型を含め値を比較 -
==
: 型は含めず値を比較 -
===
: 所属性の比較
equal?
object_id
が等しいかどうかを比較している。
a = "hello"
b = "hello"
c = a
# 値は同じだが、参照が異なるためfalse
puts a.equal?(b) # false
# 参照が同じなのでtrue
puts a.equal?(c) # true
# Stringはミュータブルなので、同じ値のStringは別々のオブジェクトIDを持つ
puts "hoge".equal?("hoge") # false
# Integerはイミュータブルなので、同じ値のIntegerは同じオブジェクトIDを持つ(nilやbooleanなども同じ)
puts 111.equal?(111) # true
eql?
オブジェクトの値を型も含めて同じかどうか比較している。
a = "hello"
b = "hello"
# 値が同じなのでtrue
puts a.eql?(b) # true
# ==との違い
a = 1
b = 1.0
# 値は同じに見えるが、クラスはIntegerとFloatで異なるためfalse
puts a.eql?(b) # false
puts a == b # true
Hashのkeyの比較はeql?
で行われている。
# それぞれのkeyはeql?でないため、このようなHashが存在しうる
hash = {1 => "aaa", 1.0 => "bbb", "hoge" => "ccc", :hoge => "ddd"}
puts hash # {1=>"aaa", 1.0=>"bbb", "hoge"=>"ccc", :hoge=>"ddd"}
===
左辺が右辺を含むかどうかを判定している(範囲、クラス、正規表現など)。
puts (1..10) === 5 # true
puts Integer === 5 # true
puts /\d+/ === "123" # true
case文のwhen句ではこの比較で分岐を行っている。
==
オブジェクトの値が等しいかどうかを判定している。
人間にはこれが一番直感的。
a = "hello"
b = "hello"
# 値が同じなのでtrue
puts a == b # true
# eql?と異なり、型の変換を行なって同値性を比較
a = 1
b = 1.0
puts a == b # true
Discussion