【发布时间】:2017-03-18 15:36:55
【问题描述】:
Setter 在类内部工作; REPL 顶层失败
在related question 中,我试图理解为什么赋值方法返回了一个意外的值,并了解到这是Ruby 中的surprising but documented edge case。然而,当我试图调试这个问题时,我更深入地了解了兔子洞并遇到了一些我无法解释的额外惊喜。
类内部的设置器
当我在一个类中有一个 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 存储实例变量,为什么类赋值方法有效而顶层赋值方法失败?我希望两者都以相同的方式发挥作用。
【问题讨论】:
-
顺便说一句:我不同意评估分配值的方法分配是一个令人惊讶的边缘情况。它的工作方式与所有其他赋值完全相同:局部变量赋值、实例变量赋值、类变量赋值、全局变量赋值、常量赋值和索引赋值。 same 工作并不符合 IMO 的“边缘情况”,当然也不足为奇。 将是一个边缘情况,并且令人惊讶的是,如果所有分配都工作相同除了一个!
标签: ruby setter instance-variables read-eval-print-loop toplevel