使用哈希定义的访问器方法动态创建对象的最简单方法是什么?例如,如果我有一个哈希:
{foo: "Foo", bar: "Bar"}
我希望拥有一个包含访问方法foo
,foo=
,bar
和bar=
的对象,其初始值为"Foo"
,{{ 1}},分别。我可以想到:
"Bar"
但是,我不需要使用相同的特定键集来拥有它们的多个实例,而是希望每次使用可能不同的键集创建它的新实例,因此使用{{创建一个新类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
的“开放性”。