我如何在Ruby中动态设置对象属性,例如:
def set_property(obj, prop_name, prop_value)
#need to do something like > obj.prop_name = prop_value
#we can use eval but I'll prefer a faster/cleaner alternative:
eval "obj.#{prop_name} = #{prop_value}"
end
使用 send 方法:
def set_property(obj, prop_name, prop_value)
obj.send("#{prop_name}=",prop_value)
end
Object#instance_variable_set()
是您正在寻找的内容,并且是您想要的更清晰的版本。your_object = Object.new
your_object.instance_variable_set(:@attribute, 'value')
your_object
# => <Object:0x007fabda110408 @attribute="value">
Ruby文档关于Object#instance_variable_set
的说明。
instance_variable_set()
实际上是在运行时为一个变量名设置实例变量。从这个意义上讲,它具有与问题中相同的效果,但是更清晰、更简洁的替代方法。 - Jochem Schulenklopper如果情况允许使用实例方法,则以下内容不算过分:
class P00t
attr_reader :w00t
def set_property(name, value)
prop_name = "@#{name}".to_sym # you need the property name, prefixed with a '@', as a symbol
self.instance_variable_set(prop_name, value)
end
end
使用方法:
p = P00t.new
p.set_property('w00t', 'jeremy')
Object.send(attribute + '=', value)
attribute
必须是一个 String
。所以如果你正在遍历一个 Symbol
数组(像我一样),你可以使用 to_s
。
Object.send(attribute.to_s + '=', value)
foo=
方法(通过属性访问器或显式方法定义),执行obj.send("foo=", "bar")
将失败。send
只是使用指定的参数调用现有方法。请参见:http://ruby-doc.org/core-1.9.3/Object.html#method-i-send。 - wyattisimoprop_name
是嵌套键(nested key)怎么办?例如foo.bar
。 - user181452@post.comments << @comment
,如何使其变得动态?我知道ActiveModel在我将其设置为从属实例时会自动更新独立实例,但只是出于好奇 :) - João Ramires