当变量改变时调用Hook

每次某个变量的值发生变化时,是否在ruby中有一个钩子?

如果为Ruby编写C扩展,实际上可以创建一个全局变量,只要有人设置它就会触发setter hook。

但是你可能不想这样做,因为你必须写一些C并且管理它可能会很痛苦。

更好的策略是使变量通过适当的方法读取和设置。 然后,当调用setter方法时,您可以执行任何操作。 这是一个将变量封装在对象中的示例:

class Foo def bar=(v) @bar = v # do some stuff end def bar @bar end end 

类似地,您可以将变量封装在模块或类中而不是对象中。

序言:我这不是一个解决方案(已经写过:没有),但也许它可以在特殊情况下提供帮助。

我的第一个想法是使用freeze来获得解决方案:

 a = "aa" a.freeze a << 'b' #can't modify frozen string (RuntimeError) 

现在我们必须重新定义freeze ,当变量改变值时我们得到一个提示:

 module FreezeWarning def freeze puts "#{self}: I am changed" end end a = "aa" a.extend(FreezeWarning) a.freeze a << 'b' #aa: I am changed 

第一个问题: 无法获取变量名称 。

您可以使用附加变量解决此问题(您可以定义自己的变量标识,它不能是名称)

 module FreezeWarning def change_warning(name) @varname = name self.freeze end def freeze puts "<#{@varname}> (#{self}): I am changed" end end a = "aa" a.extend(FreezeWarning) a.change_warning('a') a << 'b' # (aa): I am changed 

但更大的问题是:这只适用于价值的变化,而不适用于新的分配:

 a = 5 a.freeze a = 4 pa # -> 4 

所以这只是一个非常有限的“解决方案”。