我创建了一个对象,我想根据一些条件检查,为这个对象添加一些属性。我怎样才能做到这一点? 解释我想要的东西:
A=Object.new
if(something happens)
{
#make A have another attibute say age
#& store something in A.age
}
答案 0 :(得分:48)
首先,关于ruby的事情是它允许使用不同的语法,ruby编码器广泛使用它。大写标识符是类或常量(感谢sepp2k的评论),但您尝试将其作为对象。并且几乎没有人使用{}
标记多行块。
a = Object.new
if (something happens)
# do something
end
我不确定你的问题是什么,但我有一个想法,这就是解决方案:
如果您知道该类可以具有哪些属性,并且它有限,则应使用
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
如果你想完全动态地做,你可以这样做:
a = Object.new
if (some condition)
a.class.module_eval { attr_accessor :age}
a.age = new_age_value
end
答案 1 :(得分:21)
这会将属性仅添加到对象:
a = Object.new
if (something happens)
class << a
attr_accessor :age
end
a.age = new_age_value
end
答案 2 :(得分:20)
您可以使用OpenStruct:
a = OpenStruct.new
if condition
a.age = 4
end
或者只使用普通的旧哈希。
答案 3 :(得分:11)
如果在代码编写时知道属性的名称,那么您可以执行已经建议的内容:
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
但是,如果属性的名称是动态的,并且仅在运行时已知,那么您必须稍微调用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
答案 4 :(得分:6)
您可以使用instance_variable_set
在Object类的实例上设置变量(和instance_variable_get
来获取它。)Object类没有可以直接设置的任何属性。
然而,我怀疑这不是你想要实现的最佳解决方案;它不是直接使用Object类的规范,而是定义或使用从中继承的类,它们具有您想要使用的属性。
答案 5 :(得分:1)
class Person; end
person = Person.new
person.age # throws NoMethodError
if true
person.singleton_class.module_eval { attr_accessor :age }
end
person.age = 123
person.age #=> 123
person2 = Person.new
person2.age #=> throws NoMethodError