在Ruby中,对于未定义的变量“ foo”,为什么“ foo = foo”不会引发错误?

pop*_*nja 8 ruby

foo是未定义的变量时,尝试访问它会引发NameError

foo
#=> NameError: undefined local variable or method `foo'

a = foo
#=> NameError: undefined local variable or method `foo'
Run Code Online (Sandbox Code Playgroud)

为什么不foo = fooNameError

foo = foo
#=> nil
Run Code Online (Sandbox Code Playgroud)

昨天,我花了几个小时来跟踪此行,这是程序中的错误...

capture = capture.to_i
Run Code Online (Sandbox Code Playgroud)

我原本打算做的是转换capture_strInteger。相反,我所做的是nil通过说来引入a capture = capture,然后将零变为a 0。所以我在做这个...

capture = capture.to_i
#=> 0
Run Code Online (Sandbox Code Playgroud)

但是我一直错误地假设NameError会像这样抛出一个变量...

capture = capture_str.to_i
#=> NameError: undefined local variable or method `capture_str'
Run Code Online (Sandbox Code Playgroud)

mrz*_*asa 14

Ruby具有一个奇怪的功能,即在声明变量时将其吊起:

这意味着,当解析器看到x = 1时,它实际上将通过将变量赋给nil来声明该变量,然后让解释器确定x = 1行是否将被执行。

资源

所以当你写

a = a.to_i
Run Code Online (Sandbox Code Playgroud)

它首先声明a = nil然后调用to_i它并赋值:

a = nil
a = a.to_i
Run Code Online (Sandbox Code Playgroud)

编辑:

在其他情况下,它也可以像这样工作if

pry> b
NameError: undefined local variable or method `b' for main:Object
from (pry):30:in `__pry__'
pry> b if b.nil?
NameError: undefined local variable or method `b' for main:Object
from (pry):31:in `__pry__'
pry> b = 1 if b.nil?
#=> 1
pry> b
#=> 1
Run Code Online (Sandbox Code Playgroud)

和(来自链接的博客文章的示例):

if false
  x = 1
end
puts x.class
# NilClass
Run Code Online (Sandbox Code Playgroud)