オブジェクトの等値性
ややこしいのでメモ。
equal? |
ふたつの式が指すオブジェクトが同一か? |
== |
ふたつのオブジェクトの値が等しいか? |
eql? |
ハッシュキーが等しいかどうかチェックするために Hash クラスが使う。 |
=== |
case 文の when で使われる。 |
=~ |
正規表現のマッチ。 |
equal?
a = "Ruby" # => "Ruby" b = "Ruby" # => "Ruby" c = b # => "Ruby" a.object_id # => 134586220 b.object_id # => 134585530 c.object_id # => 134585530 a.equal? b # => false b.equal? c # => true
==
a = "Ruby" # => "Ruby" b = "Ruby" # => "Ruby" a.object_id # => 134586100 b.object_id # => 134585530 a.equal? b # => false a == b # => true 1 == 1.0 # => true 1 == "1" # => false # 無茶しすぎ
eql?
1 == 1.0 # => true 1.eql? 1.0 # => false
Hash ってキーとなるオブジェクトの hash を取って Fixnum として比較してるんじゃないの?
class OreOre def initialize(id) @id = id end def ==(o) @id == o.id end def eql?(o) self == o end attr_reader :id end o = OreOre.new(1) p = OreOre.new(2) q = OreOre.new(1) o == p # => false o == q # => true o.hash # => 134668880 p.hash # => 134668870 q.hash # => 134668860 o.eql? p # => false o.eql? q # => true h = {} h[o] = "o" h[p] = "p" h[q] = "q" h.size # => 3 h # => {#<OreOre:0x100dc4a0 @id=1>=>"o", #<OreOre:0x100dc48c @id=2>=>"p", #<OreOre:0x100dc478 @id=1>=>"q"}
やっぱり o.hash がキーになってるっぽい。
オレオレクラスを作ったときの ==, hash, eql? の関係は?
eql? を == 相等にしたら、hash はどうやって作ればいいのだろうか?
===
when でウマくマッチするようにする。
def foo(x) case x when (0..9) "0..9" when /\d{2}/ "/\d{2}/" when Fixnum "Fixnum" end end foo 5 # => "0..9" foo 99 # => "Fixnum" foo "99" # => "/d{2}/" foo :foo # => nil
=~
s = "Ruby" /r/i =~ s # => 0 /u/i =~ s # => 1 /b/i =~ s # => 2 /y/i =~ s # => 3 /\d/ =~ s # => nil