如何在运行时将实例变量添加到定义的类中,然后从类外部获取并设置其值?
我正在寻找一种元编程解决方案,它允许我在运行时修改类实例,而不是修改最初定义该类的源代码.一些解决方案解释了如何在类定义中声明实例变量,但这不是我要问的.
如何在运行时将实例变量添加到定义的类中,然后从类外部获取并设置其值?
我正在寻找一种元编程解决方案,它允许我在运行时修改类实例,而不是修改最初定义该类的源代码.一些解决方案解释了如何在类定义中声明实例变量,但这不是我要问的.
可以使用属性访问器:
class Array
attr_accessor :var
end
现在,您可以通过以下方式访问:
array = []
array.var = 123
puts array.var
请注意,您也可以使用attr_reader
或attr_writer
来定义getter或setter,或者手动定义它们:
class Array
attr_reader :getter_only_method
attr_writer :setter_only_method
# Manual definitions equivalent to using attr_reader/writer/accessor
def var
@var
end
def var=(value)
@var = value
end
end
如果只想在单个实例上定义,也可以使用单例方法:
array = []
def array.var
@var
end
def array.var=(value)
@var = value
end
array.var = 123
puts array.var
仅供参考,作为对该答案 comments 的回应,单例方法效果良好,以下是证据:
irb(main):001:0> class A
irb(main):002:1> attr_accessor :b
irb(main):003:1> end
=> nil
irb(main):004:0> a = A.new
=> #<A:0x7fbb4b0efe58>
irb(main):005:0> a.b = 1
=> 1
irb(main):006:0> a.b
=> 1
irb(main):007:0> def a.setit=(value)
irb(main):008:1> @b = value
irb(main):009:1> end
=> nil
irb(main):010:0> a.setit = 2
=> 2
irb(main):011:0> a.b
=> 2
irb(main):012:0>
如您所见,singleton方法setit
将设置与使用attr_访问器定义的字段相同的字段@b
...所以单例方法是解决这个问题的一个非常有效的方法.