- 追加された行はこの色です。
- 削除された行はこの色です。
&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"
}}