为什么变量只在未执行的Ruby代码中出现时才被“定义”?

以下ruby语句将导致x被“定义”(即, defined(x)返回"local-variable"即使它在执行此代码之前未定义,即使未执行赋值:

如果为假,则x = 1

具体来说, x局部变量将设置为nil 。 对于永不执行的赋值,行为类似于while falseuntil false子句。 您可以在irb中运行或在某些代码片段上运行ruby来validation这一点。

我的问题有两个:

  1. 这种行为是否记录在何处?
  2. 在任何地方都记录了这种行为的理由吗?

以下是编译器的一些见解。 这就是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分配给局部变量xjump 7跳过赋值本身( putobjectsetlocal 2 )。 puts x因此获取槽2并调用puts ; 但是,由于y在这个范围或更高的范围内都没有被识别为局部变量,所以它被认为可能是一种方法,实际上,几乎就像你有写入的puts(y()) 。 在执行时,无法解析y ,并引发错误。