Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Ruby似乎从case语句内部提升变量声明,即使代码路径没有执行?_Ruby - Fatal编程技术网

为什么Ruby似乎从case语句内部提升变量声明,即使代码路径没有执行?

为什么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

我们定义了一个函数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.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
?容易多了。