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

如果我执行这个ruby代码:

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

我得到的输出是:

 "method" 100 "local-variable" nil 

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

分配左侧的名称设置为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()

这就是我的朋友和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 aa nil

我认为这是翻译的一个怪癖,真的。 加里·伯恩哈特在wat( https://www.destroyallsoftware.com/talks/wat )中用a = a取笑它

-Josh