如何知道在Ruby中何时设置实例变量

如何知道在Ruby中何时设置实例变量,ruby,Ruby,有没有办法覆盖Ruby中实例变量的设置 假设我设置了一个实例变量: @foo = "bar" 我能截取它并做些什么吗(例如,记录它或放置) 我想,我正在尝试覆盖所有类型的赋值运算符。这能做到吗 到目前为止,我想到的最好的办法是: class Module def attr_log_accessor( *symbols ) symbols.each { | symbol | module_eval( "def #{symbol}() @#{symbol}; end" )

有没有办法覆盖Ruby中实例变量的设置

假设我设置了一个实例变量:

@foo = "bar"
我能截取它并做些什么吗(例如,记录它或放置)

我想,我正在尝试覆盖所有类型的赋值运算符。这能做到吗

到目前为止,我想到的最好的办法是:

class Module
  def attr_log_accessor( *symbols )
    symbols.each { | symbol |
      module_eval( "def #{symbol}() @#{symbol}; end" )
      module_eval( "def #{symbol}=(val) 
                      @#{symbol} = val
                      puts \"#{symbol} has changed\"
                    end" )
    }
  end
end
然后,当我定义并设置访问器时,我的代码将被执行:

class Test
  attr_log_accessor :foo

  def DoSomething
    self.foo = "bar"
  end
end
不幸的是,这需要我编写self.foo=“bar”,而不是@foo=“bar”


有什么想法吗?

没有,你不能直接这么做。最好的方法是只通过getter/setter方法访问实例变量,并覆盖它们。

您可能会搞乱,并且。更多内容可以在本文中找到


如果您能描述一下为什么要这样做,我们可能会提供更好的方法。

您可以使用
method\u missing()

例如:

def method_missing(name, *args)
  attribute = name.to_s
  if attribute =~ /=$/
    @attributes[attribute.chop] = args[0]
  else
    @attributes[attribute]
  end
end
如果在getter/setter中有处理,这个方法很快就会变得臃肿

有关更多信息,请查看OpenStruct源代码。此外,我从(第52页)中提取了此代码


另外,请注意,这将捕获所有缺少的方法。如果您只想截取
obj.[*]=
,那么您必须将
@attributes[attribute]
更改为
super

我正在尝试这样做,因为对于类上的特定属性,我希望在属性更改时通知其他对象。更具体地说,这是为了与.Net集成。我正在INotifyPropertyChanged.PropertyChanged事件上使用IronRuby并触发事件。我想将一个属性声明为notifiable:attr_notifiable:foo或其他什么,只要设置@foo,它就会触发事件。最终,self.foo将起作用,但如果我能进入底层(分配给本地var),那么它将对我更有用。有
trace_var
(),但仅适用于全局var。还有可观察模块,它可能尽可能接近这一点:然而,这可能需要使用getter/setter,而不是直接设置实例变量(现在基本上就是这样做的)