为什么变量只在未执行的Ruby代码中出现时才被“定义”?
以下ruby语句将导致x
被“定义”(即, defined(x)
返回"local-variable"
即使它在执行此代码之前未定义,即使未执行赋值:
如果为假,则x = 1
具体来说, x
局部变量将设置为nil
。 对于永不执行的赋值,行为类似于while false
, until false
子句。 您可以在irb中运行或在某些代码片段上运行ruby来validation这一点。
我的问题有两个:
- 这种行为是否记录在何处?
- 在任何地方都记录了这种行为的理由吗?
以下是编译器的一些见解。 这就是Ruby 2.0.0 x = 1 if false; puts x; puts y
转换x = 1 if false; puts x; puts y
x = 1 if false; puts x; puts y
x = 1 if false; puts x; puts y
放入( 在执行任何代码之前 ):
== disasm: @>========== local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1) [ 2] x 0000 trace 1 ( 1) 0002 jump 7 0004 putobject_OP_INT2FIX_O_1_C_ 0005 setlocal_OP__WC__0 2 0007 trace 1 0009 putself 0010 getlocal_OP__WC__0 2 0012 opt_send_simple 0014 pop 0015 trace 1 0017 putself 0018 putself 0019 opt_send_simple 0021 opt_send_simple 0023 leave
您可以看到本地表将其插槽2
分配给局部变量x
。 jump 7
跳过赋值本身( putobject
, setlocal 2
)。 puts x
因此获取槽2
并调用puts
; 但是,由于y
在这个范围或更高的范围内都没有被识别为局部变量,所以它被认为可能是一种方法,实际上,几乎就像你有写入的puts(y())
。 在执行时,无法解析y
,并引发错误。