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

时间:2019-07-10 13:07:45

标签: ruby

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

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

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

为什么foo = foo不提出NameError

foo = foo
#=> nil

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

capture = capture.to_i

我打算做的是将capture_str转换为Integer。相反,我所做的是通过说nil来引入capture = capture,然后将零变为0。所以我正在这样做...

capture = capture.to_i
#=> 0

但是我一直不正确地假设像这样会抛出变量NameError ...

capture = capture_str.to_i
#=> NameError: undefined local variable or method `capture_str'

1 个答案:

答案 0 :(得分:14)

Ruby具有怪异的功能,它在声明变量时会悬挂变量:

  

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

source

所以当你写

a = a.to_i

它首先声明a = nil,然后在其上调用to_i并分配:

a = nil
a = a.to_i

编辑:

在其他情况下(例如,与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

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

if false
  x = 1
end
puts x.class
# NilClass