LoginSignup
0
0

More than 5 years have passed since last update.

同一性・同値性判定(==,===,eql?,equal?)

Last updated at Posted at 2017-04-16

Rubyの同一性・同値性判定について軽い備忘録。

あらゆるオブジェクトは値と一意的なIDをもつ。
オブジェクトIDは .object_idメソッドで確かめられる。
例えば、

a  = 2.0
b  = 2
c = "2".to_i
d = 2.0.to_i
e = 2.to_f

puts a.object_id  #=>  23370708
puts b.object_id  #=>  5
puts c.object_id  #=>  5
puts d.object_id  #=>  5
puts e.object_id  #=>  23370708

2つのオブジェクトを比較するとき、「.equal?」、「.eql?」、「==」、「===」などを使う。aとbを比較すると

puts a.equal? b  #=>  false
puts a.eql? b    #=>  false
puts a == b      #=>  true
puts a ===b      #=>  true

==,===については同値性を、equal?はID同一性を確かめている。
eql?はクラスによって振る舞いが変わる。Stringに対しては同値性(なので「==」と同じ)、Numericに対しては同一性(なので「equal?」と同じ)の判定を行う。
別の例として

s = "puyo"
t = "pu"
u = "yo"
v = t+u
w = "pu"+"yo"

puts s  #=>  puyo
puts v  #=>  puyo
puts w  #=>  puyo

IDと同一性・同値性を確かめると

puts s.object_id  #=>  23433564
puts v.object_id  #=>  23367516
puts w.object_id  #=>  23367480

puts s.equal? v  #=>  false
puts s.equal? w  #=>  false
puts s.eql? v    #=>  true
puts s.eql? w    #=>  true
puts s == v      #=>  true        wとの比較も同様
puts s === v     #=>  true        wとの比較も同様

関連してIDについて触れておくと、NumericとStringとで決まり方が異なる

a = 2
b = 2
c = 1 + 1
puts a.object_id  #=>  5
puts b.object_id  #=>  5
puts c.object_id  #=>  5

α = "pu"
β = "yo"
x = α+β
puts x.object_id  #=>  23532144

γ = "pu"
δ = "yo"
y = γ+δ
puts y.object_id  #=>  23532084

z = "puyo"
puts z.object_id  #=>  23532060

z = "puyo"
puts z.object_id  #=>  23532036

Numericは値に対してIDが決まるが、Stringについては変数に値を格納する毎にIDが変わる

最後にハッシュについて。
ハッシュの値参照を行う際、ハッシュオブジェクトの内部では.eql?メソッドでキーIDを比較している。そのため次のような振る舞いをする。

h = {"i"+"d" => "value"}
puts h["i"+"d"]     #=> value
puts h["id"]        #=>  value

k = {2.0 => :valuable}
puts k[2.0]         #=>  valuable
puts k[2]           #=>  nil
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0