如何在运行时将实例变量添加到定义的类中,然后从类外部获取并设置其值?

我正在寻找一种元编程解决方案,它允许我在运行时修改类实例,而不是修改最初定义该类的源代码.一些解决方案解释了如何在类定义中声明实例变量,但这不是我要问的.

推荐答案

可以使用属性访问器:

class Array
  attr_accessor :var
end

现在,您可以通过以下方式访问:

array = []
array.var = 123
puts array.var

请注意,您也可以使用attr_readerattr_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...所以单例方法是解决这个问题的一个非常有效的方法.

Ruby相关问答推荐

Ruby;人;docs-使用\";?

ruby 中嵌套哈希中相同键的平均值

如何在 Shopify 脚本编辑器中显示数组值?

ruby:rubocop 抱怨将 if else 转换为 case 语句

Ruby 是否提供了一种使用指定编码执行 File.read() 的方法?

将块传递给方法传递给Ruby中的另一个方法

如何记录在 Ruby 程序中调用的每个方法?

Ruby:如何卸载设计(uninstall Devise)?

我如何 expect期望在 RSpec 中引发异常的东西?

在文件中搜索字符串的最佳方法是什么?

如何在 ruby​​ 中针对正则表达式测试整个字符串?

从字符串中删除所有特殊字符 - ruby

Ruby 将标题发布到 slug

如何在 Mac OS X Lion 中安装 Ruby 1.9.3?

如何只获取没有命名空间的类名

to_proc 方法是什么意思?

如何在 jekyll markdown 博客中包含视频

如何使用 link_to Ruby on rails 添加确认消息

Ruby - 用另一个字符串替换第一次出现的子字符串

Ruby中的字符串和符号有什么区别?