Rubyにおける等性判断の4つの方法

2268 ワード

ルビーには「===」、「=====」、「equal?」、「eql?」の4つの等性判断方法があることは早くから知られていたが、普段はプログラムで使われているが、深く理解していないような気がして、今日railsの一部のソースコードを読むときにその中の1つの判断の意味がつかめず、その機会に深く研究してみた.今日はメモを取って、メモを取ります.
"=="最も一般的な等化判断
"=="は最も頻繁に使用され、オブジェクトの値の等しい(意味の等しい)判断に一般的に使用されます.Objectのメソッド定義では、"=="は2つのオブジェクトのobject_を比較します.idが一致するかどうかは、通常、サブクラスが上書きする方法を書き換え、内部値を比較することでオブジェクトが等しいかどうかを判断します.
例えばActiveRecord::Base対"=="の定義
 
  
  def ==(comparison_object)
    super ||
      comparison_object.instance_of?(self.class) &&
      id.present? &&
      comparison_object.id == id
  end

2つのActiveRecord::Baseインスタンスが等しいかどうかmodelのidプロパティで比較します.
「===」はcase文の適合判断に使用されます.
「===」は主にcase文のオブジェクトの適合比較に用いられ、コードを見ると分かりやすい.
 
  
def what_is(obj)
  case obj
    when /abc/
      puts "include abc"
    when 3..5
      puts "in 3..5"
    when Symbol
      puts "It is a symbol"
    else
      puts "unkonwn"
  end
end

what_is("abcde") # =>  "include abc"
what_is(4)       # =>  "in 3..5"
what_is(:a)      # =>  "It is a symbol"
what_is(100)     # =>  "unknown"


caseの背後には,各whenの後ろのオブジェクトをobjと==メソッド計算で比較し,たとえば上のコードはそれぞれ/abc/.==(obj),(3..5).===(obj),Symbol.=(obj)を求める.
重要なのは==メソッドでどのように定義するか、Classクラスで==obj.is_と定義することです.a?(klass)なのでcaseは現実objのタイプ判断が可能です.
特に注意したいのは、他の等しい判断とは異なる「===」は通常交換できない、つまりa.==(b)!=b.==(a)例えば/abc/==「abcd」はtrueであるが、「abcd」==/abc/はfalseである.
「equal?」同じ対象判断
「equal?」は実は最も簡単ですが、最も混同されやすい判断です.単純に言えば、このメソッドの意味は、2つのオブジェクトが同じかどうか(同じobject_idがあるかどうか)を比較することであり、Objectのメソッドはすべてのオブジェクトに適用され、上書きを書き換えるべきではないからです.混同されやすいのは、rubyとjavaの「==」と「equal?」メソッドの意味が正反対であり、rubyの「equal?」はオブジェクト参照が同じであり、javaはオブジェクト値が同じであることを示しているからです.
「eql?」オブジェクトhash値判断
eql? オブジェクトhash値判断に使用し、2つのオブジェクトのhash値が等しい場合はtrueを返し、そうでない場合falseを返します.Objectの定義では「eql?」と「==」は等価である.通常、「eql?」は「===」よりも厳密に等しいと見なすことができます.例えば、
 
  
1 == 1.0     #=> true
1.eql? 1.0   #=> false