我有一个具有不同属性的模型。并非每个实例都有每个属性的值。
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
。
答案 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