为什么我可以引用从未运行的if/unless/case语句之外的变量?

Kow*_*hik 17 ruby

为什么以下代码不会抛出错误?

if false
  x = 0
end

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

以下确实会引发错误:

y  # NameError: undefined local variable or method `y' for main:Object
Run Code Online (Sandbox Code Playgroud)

unless&casestatements 也会发生同样的事情.

And*_*all 25

这是因为Ruby解析器的工作原理.变量由解析器定义,解析器逐行遍历代码,无论它是否实际执行.

一旦解析器看到x =,它就定义了当前范围内的局部变量x(带有值nil).由于if/ unless/ case/ for/ while不创建新范围,x因此在代码块之外定义并可用.并且由于内部块从未被评估为条件为假,x因此未分配(因此nil).

这是一个类似的例子:

defined?(x) and x = 0
x  #=> nil
Run Code Online (Sandbox Code Playgroud)

请注意,这是对所发生情况的高级概述,并不一定完全是解析器的工作方式.