使用访问器方法动态创建对象

时间:2013-02-09 16:56:23

标签: ruby accessor

使用哈希定义的访问器方法动态创建对象的最简单方法是什么?例如,如果我有一个哈希:

{foo: "Foo", bar: "Bar"}

我希望拥有一个包含访问方法foofoo=barbar=的对象,其初始值为"Foo",{{ 1}},分别。我可以想到:

"Bar"

但是,我不需要使用相同的特定键集来拥有它们的多个实例,而是希望每次使用可能不同的键集创建它的新实例,因此使用{{创建一个新类1}}每次对于每个对象看起来都是矫枉过正的,我想避免这种情况。有更好的方法吗?

1 个答案:

答案 0 :(得分:12)

OpenStruct已经提供了您想要的内容:

require 'ostruct'

o = OpenStruct.new foo: "Foo", bar: "Bar"
o.foo  #=> "Foo"
o.bar  #=> "Bar"
o.bar = 'BAR'
o.bar  #=> "BAR"

或者,如果您不希望在创建对象后能够定义任意属性(就像使用OpenStruct一样,您可以执行以下操作:

class ObjectWithAccessor
  def initialize attrs
    attrs.each do |name, val|
      singleton_class.send :attr_accessor, name.to_sym
      public_send :"#{name}=", val
    end
  end
end

o = ObjectWithAccessor.new foo: "Foo", bar: "Bar"
o.foo           #=> "Foo"
o.bar           #=> "Bar"
o.bar = 'BAR'
o.bar           #=> "BAR"
o.bsr = 'typo'  #=> #<NoMethodError: undefined method `bsr=' for #<Object:0x007fa4160847f8>>

这仍然不会创建一个新类只是为了使用它一次,并避免OpenStruct的“开放性”。