どれが何なのかたまに混乱するのでメモ.
==
- オブジェクトの同値性のチェック
- クラスやオブジェクトの性質に合わせて再定義できる
===
- オブジェクトの同値性のチェック(所属性を加味)
- case式で使われる
- クラスやオブジェクトの性質に合わせて再定義できる
eql?
- オブジェクトの同値性のチェック(==より厳密)
- Hashで二つのキーが等しいかどうかを判定するのに使われる
- クラスやオブジェクトの性質に合わせて再定義できる
- 再定義した場合はhashメソッドも再定義しなければならない
equal?
- オブジェクトの同一性のチェック
- object_idが一致するかどうかを調べる
- 再定義してはならない
比較表
効果 | 使用場面 | 再定義 | |
== | 同値性のチェック | 同値性のチェック | ○ |
=== | 同値性のチェック(所属性) | case式 | ○ |
eql? | 同値性のチェック(厳密) | Hashキーの比較 | ○(※) |
equal? | 同一性のチェック | 同一性のチェック | × |
例
Numeric#==,Numeric#===は両辺が数値的に等しければtrue.Numeric#eql?は両辺が数値的に等しくてもクラスが同じでなければfalse.
1 == 1.0 #=> true 1 === 1.0 #=> true 1.eql?(1.0) #=> false 3.14 == 3.14000 #=> true 3.14 === 3.14000 #=> true 3.14.eql?(3.14000) #=> true
Regexp#===は右辺のStringが左辺の正規表現にマッチすればtrue.
/foo/ == "foo" #=> false /foo/ === "foo" #=> true /foo/ === "bar" #=> false "foo" === /foo/ #=> false # String#===が呼び出されている
Range#===は右辺のオブジェクトが左辺に含まれるならばtrue.
(0..10) == 1 #=> false (0..10) === 1 #=> true 1 === (0..10) #=> false # Fixnum#===が呼び出されている
Module#===,Class#===は右辺のオブジェクトが左辺のクラスかそのサブクラスのインスタンスならばtrue.
Numeric === 1.0 #=> true Integer === 1.0 #=> false
equal?は両辺のオブジェクトのobject_idが等しければtrue.Symbolは同じ内容ならば必ず同一object_idになる.
a = b = "foo" a.equal?(b) #=> true a = "bar" b = "bar" a.equal?(b) #=> false a = :baz b = :baz a.equal?(b) #=> true
以上
基本的に==を使っていれば事足りそうではあるが,===についてはクラスごとの性質を知っておくとcase式の書き方の幅が広がるので知っておく価値はありそう.
n = 10 ** 100 # nは === の右辺になる type = case n when Fixnum "int" when Bignum "longer than int" when Float "double" else "something else" end puts type #=> longer than int