2

我有一个具有不同属性的模型。并非每个实例的每个属性都有一个值。

class Location

  attr_accessible :name,     # string, default => :null
                  :size,     # integer, default => 0
                  :latitude, # float, default => 0
                  :longitude # float, default => 0

  # Returns a unique hash for the instance.
  def hash
   # ...
  end

end

如何实现返回实例唯一 ID 的哈希函数?每次我在对象上调用散列函数时,它都应该是相同的。我不想要一个随机的唯一 ID。应该可以将散列存储在 sqlite3 数据库中而无需修改。


正如您在MetaSkills 的回答中所读到的,覆盖该方法并不是一个好主意,hash因为它“被大量 ruby​​ 对象用于比较和相等”。因此,我将其重命名为custom_attributes_hash.

4

1 回答 1

6
require 'digest/md5'

class Location

  attr_accessor :name,     # string, default => :null
                  :size,     # integer, default => 0
                  :latitude, # float, default => 0
                  :longitude # float, default => 0

  # Returns a unique hash for the instance.
  def hash
    Digest::MD5.hexdigest(Marshal::dump(self))
  end

end

用撬测试

[1] pry(main)> foo = Location.new;
[2] pry(main)> foo.name = 'foo';
[3] pry(main)> foo.size = 1;
[4] pry(main)> foo.latitude = 12345;
[5] pry(main)> foo.longitude = 54321;
[6] pry(main)> 
[7] pry(main)> foo.hash
=> "2044fd3756152f629fb92707cb9441ba"
[8] pry(main)> 
[9] pry(main)> foo.size = 2
=> 2
[10] pry(main)> foo.hash
=> "c600666b44eebe72510cc5133d8b4afb"

或者您也可以创建自定义函数来序列化属性。例如使用所有的实例变量

def hash
  variables = instance_variables.map {|ivar| instance_variable_get(ivar)}.join("|separator|")
  Digest::MD5.hexdigest(variables)
end

或选择您需要的

def hash
  variables = [name, size].join("|separator|")
  Digest::MD5.hexdigest(variables)
end
于 2013-07-17T03:48:45.103 回答