Setter 在类内工作;REPL 顶层失败
在一个相关的问题中,我试图理解为什么赋值方法返回了一个意外的值,并了解到这是一个令人惊讶但记录在案的 Ruby 边缘案例。然而,当我试图调试这个问题时,我更深入地了解了兔子洞,并遇到了一些我无法解释的额外惊喜。
类内的二传手
当我在一个类中有一个 setter 方法时,例如:
class Setter
def foo=(bar)
@foo = Integer(bar).succ
end
end
然后我从 setter 方法的返回值中得到了记录的奇怪,但实例变量仍然设置正确。例如:
s = Setter.new
s.foo = 1
#=> 1
s.instance_variable_get :@foo
#=> 2
REPL 顶级对象中的设置器
但是,在 REPL(例如 Pry 或 IRB)中,实例变量从未实际设置,尽管我的理解是实例变量应该存储在顶层“主”对象中:
self.name
#=> NoMethodError: undefined method `name' for main:Object
# This is expected to set the @foo instance variable for main.
def foo= int
@foo = int
end
foo = 1
@foo
#=> nil
instance_variable_get :@foo
#=> nil
TOPLEVEL_BINDING.eval('self').instance_variables
#=> []
然而,顶层对象确实存储了实例变量!例如:
@bar = 1 + 1; @bar
#=> 2
instance_variable_get :@bar
#=> 2
问题,重述
鉴于 REPL 存储实例变量,为什么类赋值方法有效而顶层赋值方法失败?我希望两者都以相同的方式运作。