为什么Ruby似乎从case语句内部提升变量声明,即使代码路径没有执行?
我们定义了一个函数foo:为什么Ruby似乎从case语句内部提升变量声明,即使代码路径没有执行?,ruby,Ruby,我们定义了一个函数foo: def foo(s) case s when'foo' x = 3 puts x.inspect when 'bar' y = 4 puts y.inspect end puts x.inspect puts y.inspect end 我们称之为: 1.9.3p194 :017 > foo('foo') in foo scope 3 in outer scope 3 nil => nil 1
def foo(s)
case s
when'foo'
x = 3
puts x.inspect
when 'bar'
y = 4
puts y.inspect
end
puts x.inspect
puts y.inspect
end
我们称之为:
1.9.3p194 :017 > foo('foo')
in foo scope
3
in outer scope
3
nil
=> nil
1.9.3p194 :018 > foo('bar')
in bar scope
3
in outer scope
nil
3
=> nil
为什么函数在这两种情况下都不会抛出有关未注册局部变量的错误?在第一种情况下,变量y
似乎不应该存在,因此不能在外部范围内对其调用inspect
;在第二种情况下,x
的情况相同
下面是另一个类似的例子:
def test1
x = 5 if false
puts x.inspect
end
def test2
puts x.inspect
end
然后:
1.9.3p194 :028 > test1
nil
=> nil
1.9.3p194 :029 > test2
NameError: undefined local variable or method `x' for main:Object
这是怎么回事?看起来Ruby正在将变量声明提升到外部范围中,但我不知道Ruby会这样做。(搜索“ruby提升”只会显示关于JavaScript提升的结果。)ruby解析器遍历每一行,并设置为nil all
variable=
。代码是否实际执行并不重要
看
当Ruby解析器看到序列标识符、等号、值、,
就像这句话一样
x = 1
它为名为x
的局部变量分配空间。创建
变量不是赋值给它,而是内部变量
变量的创建总是由于这种类型的
表达式,即使代码没有执行!考虑这个例子:
if false
x = 1
end
p x # Output: nil
p y # Fatal Error: y is unknown
对x
的赋值未执行,因为它被封装在一个失败的
条件测试。但是Ruby解析器从中看到序列x=1
它推断程序涉及一个局部变量x
。这个
解析器并不关心x是否被赋值。它的工作是
只是为了在代码中搜索需要空间的局部变量
被分配。结果是x处于一种奇怪的可变的边缘。
它已产生并初始化为nil
。
在这方面,它不同于一个根本不存在的变量
全部的正如您在示例中所看到的,检查x
会得到值
nil
,而尝试检查不存在的变量y
结果
在一个致命的错误中。但是,尽管x
存在,但它并没有在这方面发挥任何作用
节目。它仅作为解析过程的工件存在
基础扎实的红宝石家第6.1.2章-1。在你的
1.9.3p194:018>foo('bar')
中,你不应该得到你描述的结果。你知道你可以做px
而不是put x.inspect
?容易多了。