如果我有这门课程:
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)
应该使每个实例变量初始化为散列中具有相同名称的变量。
答案 0 :(得分:51)
您可以在班级上定义初始化函数:
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
之类的内容答案 1 :(得分:14)
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
答案 2 :(得分:9)
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中隐含的警告:
将符号的实例变量名称设置为object,从而使类的作者尝试提供适当的封装的努力受挫。在此调用之前,变量不必存在。