&tag(Ruby/基本); *目次 [#wafe301a] #contents *関連ページ [#pba8ab9b] *参考情報 [#vd717d70] **等値の違い [#c4f107f7] *等値の違い [#c4f107f7] **等値で使用する演算子 [#b9b13955] -EffectiveRubyによるとオブジェクトが等しいかどうかをチェックする方法が4種類ある。 -equal? オブジェクトが同じものかどうかを比較。 --同じ参照先かどうかを比較。 --object_idを比較。 -== 各クラスで定義可能で同じ値かどうかを比較 --StringやFixnum、Floatで有効。 --デフォルト実装はequal?となる。 --<=>を定義してComparableモジュールをmixinすれば自動的に定義される。 -eql? Hashキーとして使用する場合に使われる。 --デフォルトでequal?となる。 --Hashはキーオブジェクトのhashメソッドを呼び出す。hashは同じキーを表す2つのオブジェクトは同じ値を返す必要がある。ただし異なるオブジェクトが同じhash値を返しても良く、この場合equal?で追加の試験が行われる。hashが等しく、かつeql?でtrueが返ってきたモノが同じキーとみなされる。 #pre{{ class Color attr_reader :name def hash name.hash end def eql?(other) name.eql?(other.name) end }} --==は数値クラスで型変換を行うため、もう少し厳しい比較を行うために必要。 -=== case等値演算子。 --switch-case分で使われる --例えばRegexならば正規表現のマッチというふうに使うためのもの。 **<=>とComparableで比較を実践する [#mb9275ba] -Comparableをincludeして<=>を実装すれば自動的に==も実装される。 -追加でhashとeql?を実装すればハッシュのキーとしても使える #pre{{ # coding: utf-8 class Version # 各バージョン番号が等しい場合同値とみなすバージョンクラス # Comparableをincludeして<=>演算子を実装し、比較可能(これで==演算子が自動的に定義される) # eql?を==のaliasとし、hash演算子を定義することでハッシュのキーとしても利用可能 include Comparable attr_accessor :major, :minor, :patch def initialize(major, minor, patch) @major = major @minor = minor @patch = patch end def <=> (other) # 比較対象のクラスをチェック return nil unless other.is_a?(Version) # 各バージョンの比較結果がzero以外を返したときはその比較結果を返す。全く同じ場合は0を返す [major <=> other.major, minor <=> other.minor, patch <=> other.patch].detect {|n| !n.zero?} || 0 end alias_method :eql?, :== def hash # Effective Rubyによるhash値の実装 [major, minor, patch].hash end end if __FILE__ == $0 v1 = Version.new(2, 10, 4) v2 = Version.new(2, 1, 1) p [v1, v2].sort h = {} v1a = Version.new(3, 2, 4) v1b = Version.new(3, 2, 4) h[v1a] = "test" p h[v1a] p h[v1b] end }} -結果 #pre{{ [#<Version:0x007f9fcba3a940 @major=2, @minor=1, @patch=1>, #<Version:0x007f9fcba3a968 @major=2, @minor=10, @patch=4>] "test" "test" }}