有没有办法通过哈希初始化对象?

时间:2009-10-15 14:16:57

标签: ruby hash constructor initialization

如果我有这门课程:

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)

应该使每个实例变量初始化为散列中具有相同名称的变量。

3 个答案:

答案 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,从而使类的作者尝试提供适当的封装的努力受挫。在此调用之前,变量不必存在。