使用attr_accessor动态创建类属性
在Ruby中,有没有办法动态地将实例变量添加到类中? 例如:
class MyClass def initialize create_attribute("name") end def create_attribute(name) attr_accessor name.to_sym end end o = MyClass.new o.name = "Bob" o.name
一种方法(还有其他方法)是使用instance_variable_set
和instance_variable_get
如下所示:
class Test def create_method( name, &block ) self.class.send( :define_method, name, &block ) end def create_attr( name ) create_method( "#{name}=".to_sym ) { |val| instance_variable_set( "@" + name, val) } create_method( name.to_sym ) { instance_variable_get( "@" + name ) } end end t = Test.new t.create_attr( "bob" ) t.bob = "hello" puts t.bob
也许 ,
instance_variable_set(name,value)
是你想要的!
例如:
class Mclass def show_variables puts self.class.instance_variables end end Mclass.instance_variable_set(:@test,1) o=Mclass.new o.show_variables
你知道,阶级也是对象。
在另一条评论中回答@ ericso的评论/问题,所以这里是一个答案 – 我使用的模块(基于@ ReeseMoore的代码)来做这个并设置实例变量,如果有必要:
# adds ability to dynamically create instance vars & attr_accessors module Attributable def create_method(name, &block) self.class.send(:define_method, name.to_sym, &block) end def create_setter(m) create_method("#{m}=".to_sym) { |v| instance_variable_set("@#{m}", v) } end def create_getter(m) create_method(m.to_sym) { instance_variable_get("@#{m}") } end def set_attr(method, value) create_setter method send "#{method}=".to_sym, value create_getter method end end