2013-07-16 56 views
1

我有一個具有不同屬性的模型。並非每個實例都具有每個屬性的值。如何根據類屬性生成唯一的對象散列?

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讀它是不是一個好主意覆蓋hash方法,因爲它「所使用的一噸紅寶石的比較和平等的對象」。我將因此將其重命名爲custom_attributes_hash

回答

3
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 
+0

尼斯。有沒有一種方法可以定義哪些屬性參與構建散列? – JJD

相關問題