2012-09-06 28 views
5

我在項目中使用Struct而不是簡單的Hash來爲鍵值對的集合提供語義名稱。然而,一旦我構建了結構,我需要輸出一個散列值。我在Ruby 1.9.3中。例如:將to_hash(或to_h)方法添加到Struct的優雅方式?

MyMeaninfulName = Struct.new(:alpha, :beta, :gamma) do 
    def to_hash 
    self.members.inject({}) {|h,m| h[m] = self[m]; h} 
    end 
end 

my_var = MyMeaningfulName.new 
my_var.to_hash # -> { :alpha=>nil, :beta=>nil, :gamma=>nil } 

是否有一個原因,結構不包括to_hash方法?這似乎是天作之合,但也許有一個根本原因,它不包括在內。其次,有沒有一種更優雅的方法來將一個通用to_hash方法構建到Struct中(通常是通過monkeypatching,或者通過模塊或繼承)。

+0

爲了澄清問題的第二部分......因爲結構是類的工廠,我真的不知道如何添加to_hash功能(這將是很容易在任何傳統類)。 – GSP

+0

如果您想澄清,您可以編輯問題 - 只需點擊問題文本下的**編輯**鏈接即可。順便說一句,好問題。 +1! – Linuxios

回答

0

試試這個:

class Struct 
    old_new = self.method(:new) 
    def self.new(*args) 
    obj = old_new.call(*args) 
    obj.class_exec do 
     def to_hash 
     self.members.inject({}) {|h,m| h[m] = self[m]; h} 
     end 
    end 
    return obj 
    end 
end 
+0

當我嘗試:'class MyClass

2

或本:

class Struct 
    def to_hash 
    self.class.members.inject({}) {|h,m| h[m] = self[m]} 
    end 
end 

(請注意多級去的成員)

+0

我得到'未定義的局部變量或方法old_new' for Struct:Class'我認爲你的注入塊缺少'h'作爲返回值;這對我來說是個例外。或者使用'each'並將'h'移動到外部範圍。 – waldrumpus

+0

我在這個答案和Linuxios之間被撕裂了。他更羅嗦,但對我來說,更確切地說明發生了什麼事。 – GSP

+0

@waldrumpus - 代碼運行良好 - 多麼奇怪 – froderik

2

我不知道爲什麼,但它似乎是顯而易見的。幸運的是,您可以在許多地方將它用作散列,因爲它實現了括號運算符。

無論如何,這是相當優雅:

MyMeaningfulName = Struct.new :alpha, :beta, :gamma do 
    def to_hash 
    Hash[members.zip values] 
    end 
end 

my_var = MyMeaningfulName.new 1, 2, 3 
my_var.to_hash # => {:alpha=>1, :beta=>2, :gamma=>3} 
3

我知道這個問題是關於Ruby 1.9.3,但紅寶石2.0.0開始,Structto_h方法,做這項工作。

MyMeaningfulName = Struct.new(:alpha, :beta, :gamma) 

my_var = MyMeaningfulName.new 
my_var.to_h # -> { :alpha=>nil, :beta=>nil, :gamma=>nil } 
相關問題