我的印象是
Ruby中的类定义可以重新打开:
class C def x puts 'x' end end class C def y puts 'y' end end
这按预期工作,y被添加到原始类定义中.
我很困惑为什么下面的代码不能按预期工作:
class D x = 12 end class D puts x end
这将导致NameError异常.为什么在重新打开课程时会启动新的本地范围?这似乎有点违反直觉.在扩展类时,有没有办法继续以前的本地范围?
解决方法
局部变量不与对象关联,它们与范围相关联.
局部变量是词法范围的.你要做的事情不仅仅是:
def foo x = :hack if false # Ensure that x is a local variable p x if $set # Won't be called the first time through $set = x = 42 # Set the local variable and a global flag p :done end foo #=> :done foo #=> nil (x does not have the value from before) #=> done
在上面,它是在同一个对象上的同一个方法,它被执行两次.自我没有改变.但是,在调用之间清除局部变量.
重新打开类就像再次调用一个方法:您处于相同的自我范围内,但是您正在启动一个新的本地上下文.当您使用end关闭D类块时,将丢弃您的局部变量(除非它们是closed over).