如果我有這個類:有沒有辦法通過哈希來初始化一個對象?
class A
attr_accessor :b,:c,:d
end
和驗證碼:
a = A.new
h = {"b"=>10,"c"=>20,"d"=>30}
是有可能的對象直接從哈希初始化,沒有我需要去每對,並呼籲instance_variable_set
?喜歡的東西:
a = A.new(h)
這應該引起每個實例變量初始化爲具有哈希同名的人。
如果我有這個類:有沒有辦法通過哈希來初始化一個對象?
class A
attr_accessor :b,:c,:d
end
和驗證碼:
a = A.new
h = {"b"=>10,"c"=>20,"d"=>30}
是有可能的對象直接從哈希初始化,沒有我需要去每對,並呼籲instance_variable_set
?喜歡的東西:
a = A.new(h)
這應該引起每個實例變量初始化爲具有哈希同名的人。
您可以在類中定義的初始化函數:
class A
attr_accessor :b,:c,:d
def initialize(h)
h.each {|k,v| public_send("#{k}=",v)}
end
end
或者你可以創建一個模塊,然後
module HashConstructed
def initialize(h)
h.each {|k,v| public_send("#{k}=",v)}
end
end
class Foo
include HashConstructed
attr_accessor :foo, :bar
end
「它混合」或者你可以嘗試像constructor
instance_variable_set
適用於這種用例:
class A
def initialize(h)
h.each {|k,v| instance_variable_set("@#{k}",v)}
end
end
這是一個公共方法,所以你也可以把它建成後:
a = A.new({})
a.instance_variable_set(:@foo,1)
但要注意在documentation隱含警告:
由符號設置實例變量名對象,因此挫敗了班級作者試圖提供適當封裝的努力。此調用之前,變量不必存在。
對我來說,檢查以確保你只能設置定義中指定的那些重要的是,這使得這個建議不值得。 – 2013-10-17 04:45:52
OpenStruct
是值得考慮的:
require 'ostruct' # stdlib, no download
the_hash = {"b"=>10, "c"=>20, "d"=>30}
there_you_go = OpenStruct.new(the_hash)
p there_you_go.C#=> 20
是的!你也可以將JSON轉換成OpenStruct,這很好。 'JSON.parse({a:1,b:2} .to_json,object_class:OpenStruct)' – 2015-08-10 03:27:14
+1。順便說一句,你可能要考慮使用'public_send'而不是'send'來避免調用私有屬性編寫器:) – epidemian 2014-02-21 18:48:20
+ 1爲構造函數gem – 2014-07-23 15:47:00