如何根据类属性生成唯一对象哈希?

时间:2013-07-16 21:33:04

标签: ruby hash sqlite uniqueidentifier

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

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数据库中。


正如您在answer by MetaSkills中所读到的那样不是一个好主意,因为“被大量的红宝石对象使用,所以<{1}}方法会覆盖为了比较和平等“。因此,我将其重命名为hash

1 个答案:

答案 0 :(得分:4)

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

用pry测试

[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