2

これが私のRailsクラスです

class SkinnyEmployee
  include ActiveModel::Validations

  attr_accessor :uid, :name

  validates :uid, :presence => true

  def initialize(id, name)
    @uid = id
    @name = name
  end

  def ==(other)
    puts "Calling =="
    raise ArgumentError.new("other is nil or bad in "+self.to_s) if other.nil? or !other.instance_of?(SkinnyEmployee)
    return (self.class == other.class && self.uid == other.uid)
  end

  alias :eql? :==

end

SkinnyEmployee オブジェクトのハッシュがあります。例えば、

skinny_hash = {SkinnyEmployee.new("123", "xyz") => 1, SkinnyEmployee.new("456", "abc") => 2}

検索したい別の SkinnyEmployee オブジェクトがあります。例えば、

entry = SkinnyEmployee.new("456", "abc")

私がする時

skinny_hash.keys.index(entry)

予想どおり、1を取得します。しかし、私がするとき

skinny_hash.has_key?(entry)

私は偽になります。

何故ですか?has_key はありませんか? == または eql も使用しますか? キーがハッシュに存在するかどうかを調べるには?

助けてくれてありがとう!

4

3 に答える 3

0

まず、これは私を夢中にさせました。あなたがやっていることは私には完全に正しいように見えました.そして、あなたがすでに知っているように、うまくいきません.

解決への道のりの一部をご案内します。

http://ruby-doc.org/core-2.0.0/Object.html#method-i-hash

引用:

このオブジェクトの Fixnum ハッシュ値を生成します。この関数には、a.eql?(b) が a.hash == b.hash を意味するというプロパティが必要です。

ハッシュ値は eql? とともに使用されます。Hash クラスによって、2 つのオブジェクトが同じハッシュ キーを参照しているかどうかを判断します。Fixnum の容量を超えるハッシュ値は、使用前に切り捨てられます。

追加した:

def hash
    1
end

あなたの SkinnyEmployee クラスに、そして has_key? true を返し始めました。明らかにそれは解決策ではありませんが、少なくとも解決策への道を歩むことになると思います.

于 2013-10-17T00:19:45.910 に答える
0

これは、キーとして使用しているオブジェクトと、キーの検索に使用しているオブジェクトが異なるために発生しています。

SkinnyEmployee.new を呼び出すたびに、新しい異なるオブジェクトが作成されます。例えば

employee_1 = SkinnyEmployee.new("123", "xyz")
employee_2 = SkinnyEmployee.new("123", "xyz")

employee_1 == employee_1 #=> true
employee_2 == employee_2 #=> true
employee_2 == employee_1 #=> false

object_id両方employee_1を呼び出すと、employee_2異なる ID が返されることに気付くでしょう。

has_key を使用していますか? はまったく同じオブジェクトをチェックしますが、 を使用する場合はそうではありませんSkinnyEmployee.new("456", "abc")

まったく同じオブジェクトを取得し、それを変数または DB に格納する方法が必要です。キーとして使用し、それを has_key の属性として使用しますか? それが機能するために。

これがあなたを助けることを願っています。

于 2013-10-17T00:45:43.943 に答える