Ruby:方法莫名其妙地被覆盖并设置为nil

时间:2011-12-14 14:16:01

标签: ruby local-variables

如果我执行这个ruby代码:

def foo
  100
end

p defined?(foo), foo
if false
  foo = 200
end
p defined?(foo), foo

我得到的输出是:

"method"
100
"local-variable"
nil

有人可以向我解释为什么foo在未执行if之后被设置为nil?这是预期的行为还是红宝石?

2 个答案:

答案 0 :(得分:5)

分配左侧的名称设置为nil,即使代码无法在if false情况下到达。

>> foo
NameError: undefined local variable or method `foo' for main:Object
...
>> if false
..   foo = 1
..   end #=> nil
>> foo #=> nil

当Ruby尝试解析裸字时,它首先会查找局部变量(在Pickaxe书中有一个引用,我现在似乎无法找到)。由于您现在有一个名为foo,因此会显示nil。正如Mischa所说,该方法仍然可以称为foo()

答案 1 :(得分:1)

这是我的朋友和Ruby超级专家Josh Cheek所说的:

当Ruby看到赋值时,它会初始化当前作用域中的变量并将其设置为nil。由于赋值没有运行,它没有更新foo的值。

if语句不像块那样改变范围。这也是

之间最重要的区别
for x in xs

xs.each { |x| }

这是另一个例子:

a = 123 if a  # => nil
a  # => nil

我们不应该说if a,因为我们从未设置a,但Ruby会看到a = 123并初始化a,然后转到if a此时anil

我认为这是翻译的一个怪癖,真的。加里·伯恩哈特用a = a

在wat(https://www.destroyallsoftware.com/talks/wat)中取笑它

-Josh