在irb中尝试以下内容:(我使用的是Ruby 2.0.0-p247)
blah
#=> NameError: undefined local variable or method `blah' for main:Object
if false
blah = 'blah'
end
#=> nil
blah
#=> nil
即使blah
条件评估为nil
,我也很惊讶if
被分配false
。
我认为if
中的代码被跳过,条件评估为false
。
有Ruby内部知识的人能否解释一下这是怎么发生的?
谢谢
答案 0 :(得分:9)
ruby中的局部变量是在解析/编译代码(非执行)期间创建的。它们是词法范围的,因此局部变量在分配给它的行之前是不可见的。
defined?(foo) # => nil
if false
defined?(foo) # =>
foo = 'blah'
defined?(foo) # =>
end
defined?(foo) # => "local-variable"
foo # => nil
defined?(foo)
内的 if
行没有返回任何内容,因为它们没有运行。分配也没有执行。但是,编译器看到了对局部变量的赋值并创建了一个(默认值为nil
)。
此行为解释了来自WAT talk的技巧:
a = a # => nil
即使变量a
不存在,也会在此行之前创建(并设置为nil),因为代码中有一个赋值表达式(其目标是未知的局部变量) 。因此,当评估此表达式的右侧时,a
存在。