dynamic地将属性添加到R​​uby对象

我有一个对象创build,我想,基于一些条件检查,添加一些属性到这个对象。 我怎样才能做到这一点? 解释我想要的:

A=Object.new if(something happens) { #make A have another attibute say age #& store something in A.age } 

首先关于ruby的一点是,它允许使用ruby编码器广泛使用的不同的语法。 大写的标识符是类或常量(感谢sepp2k的评论),但你试图使它成为一个对象。 几乎没有人使用{}标记多行块。

 a = Object.new if (something happens) # do something end 

我不确定你的问题是什么,但我有一个想法,这将是解决scheme:

如果你知道这个类可以拥有什么属性,而且它是有限的,你应该使用

 class YourClass attr_accessor :age end 

attr_accessor :age是:

 def age @age end def age=(new_age) @age = new_age end 

现在你可以做这样的事情:

 a = YourClass.new if (some condition) a.age = new_value end 

如果你想完全dynamic的做,你可以做这样的事情:

 a = Object.new if (some condition) a.class.module_eval { attr_accessor :age} a.age = new_age_value end 

这只将属性添加到对象:

 a = Object.new if (something happens) class << a attr_accessor :age end a.age = new_age_value end 

你可以使用OpenStruct:

 a = OpenStruct.new if condition a.age = 4 end 

或者只是使用一个普通的旧散列。

如果在编写代码时已知属性的名称,那么您可以执行已经build议的内容:

 class A end a = A.new a.age = 20 # Raises undefined method `age=' # Inject attribute accessors into instance of A class << a attr_accessor :age end a.age = 20 # Succeeds a.age # Returns 20 b = A.new b.age # Raises undefined method, as expected, since we only modified one instance of A 

但是,如果属性的名称是dynamic的,只有在运行时才知道,那么您必须以不同的方式调用attr_accessor

 attr_name = 'foo' class A end a = A.new a.foo = 20 # Raises undefined method `foo=' # Inject attribute accessors into instance of A a.instance_eval { class << self; self end }.send(:attr_accessor, attr_name) a.foo = 20 # Succeeds a.foo # Returns 20 

您可以使用instance_variable_set在Object类的instance_variable_set上设置variables(以及instance_variable_get来获取它).Object类没有任何可以直接设置的属性。

不过,我怀疑这不是你想要达到的最好的解决scheme; 直接使用Object类不是常态,而是定义或使用从它inheritance的类,它们具有要使用的属性。