我们定义一个函数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
Run Code Online (Sandbox Code Playgroud)
然后我们将其称为如下:
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
Run Code Online (Sandbox Code Playgroud)
为什么函数不会在任何一种情况下抛出关于未注册的局部变量的错误?在第一种情况下,变量y似乎不应该存在,所以你不能inspect在外部范围内调用它; 同为x在第二种情况下.
这是另一个类似的例子:
def test1
x = 5 if false
puts x.inspect
end
def test2
puts x.inspect
end
Run Code Online (Sandbox Code Playgroud)
然后:
1.9.3p194 :028 > test1
nil
=> nil
1.9.3p194 :029 > test2
NameError: undefined local variable or method `x' for main:Object
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?看起来Ruby正在将变量声明提升到外部范围,但我不知道这是Ruby所做的事情.(搜索"ruby hoisting"只会显示有关JavaScript提升的结果.)
ck3*_*k3g 60
当Ruby解析器看到序列标识符时,等号,值,就像在这个表达式中一样
Run Code Online (Sandbox Code Playgroud)x = 1它为一个名为的局部变量分配空间
x.变量的创建 - 不是赋值给它,而是变量的内部创建 - 总是作为这种表达式的结果发生,即使代码没有被执行!考虑这个例子:Run Code Online (Sandbox Code Playgroud)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存在,但它在该计划中没有发挥任何作用.它仅作为解析过程的工件存在.
有根据的Rubyist第6.1.2章
| 归档时间: |
|
| 查看次数: |
3830 次 |
| 最近记录: |