53

単純な構造体のようなクラスの場合:

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 を使用する必要がありますか?

4

3 に答える 3

75

複数の状態変数を持つオブジェクトの比較演算子を単純化するには、オブジェクトのすべての状態を配列として返すメソッドを作成します。次に、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

これらは公開する必要があります。

于 2009-12-26T19:33:07.487 に答える
1

通常は==オペレーターと一緒です。

def == (other)
  if other.class == self.class
    @name == other.name && @num_stripes == other.num_stripes
  else
    false
  end
end
于 2009-12-19T01:25:09.403 に答える