単純な構造体のようなクラスの場合:
class Tiger
attr_accessor :name, :num_stripes
end
==
、===
、eql?
などが機能し、クラスのインスタンスがセットやハッシュなどでうまく機能するようにするために、同等性を正しく実装する正しい方法は何ですか。
[〜#〜]編集[〜#〜]
また、クラスの外部に公開されていない状態に基づいて比較したい場合に、平等を実装するための優れた方法は何ですか?例えば:
class Lady
attr_accessor :name
def initialize(age)
@age = age
end
end
ここでは、平等方法で@ageを考慮に入れたいのですが、Ladyは彼女の年齢をクライアントに公開していません。この状況でinstance_variable_getを使用する必要がありますか?
複数の状態変数を持つオブジェクトの比較演算子を簡略化するには、オブジェクトのすべての状態を配列として返すメソッドを作成します。次に、2つの状態を比較します。
class Thing
def initialize(a, b, c)
@a = a
@b = b
@c = c
end
def ==(o)
o.class == self.class && o.state == state
end
protected
def state
[@a, @b, @c]
end
end
p Thing.new(1, 2, 3) == Thing.new(1, 2, 3) # => true
p Thing.new(1, 2, 3) == Thing.new(1, 2, 4) # => false
また、クラスのインスタンスをハッシュキーとして使用できるようにする場合は、次を追加します。
alias_method :eql?, :==
def hash
state.hash
end
これらは公開する必要があります。
すべてのインスタンス変数の同等性を一度にテストするには:
def ==(other)
other.class == self.class && other.state == self.state
end
def state
self.instance_variables.map { |variable| self.instance_variable_get variable }
end
通常は==
演算子。
def == (other)
if other.class == self.class
@name == other.name && @num_stripes == other.num_stripes
else
false
end
end