从新开始的会话中考虑以下irb片段:
irb:01> baz # => NameError, baz is not defined
irb:02> baz || baz = 0 # => NameError, baz is not defined
irb:03> baz # => nil
baz
是一个未定义的变量,尝试评估它会产生NameError
。然而,不知何故,在此操作之后,baz
被定义,其值为nil
。看起来,值nil
已分配给变量baz
,即使没有人(明确地)要求它。是否存在潜在的语言原因,为什么这种行为是可取的?
解释此行为和其他类似令人困惑的结构的规则是什么,例如:
irb:04> true if foo # => NameError
irb:05> foo # => NameError; name still undefined
irb:06> foo = (true if foo) # => nil
irb:07> foo # => nil; name defined as nil
irb:08> true || i = 0 || j = 2 # => i and j are nil; || appears nonlazy
irb:09> raise || quux = 1 # => RuntimeError, quux is nil
答案 0 :(得分:9)
我不知道它是否可取,但它来自Ruby如何解析代码。只要有一段代码分配局部变量,即使未评估该段代码,也会为该局部变量分配nil
。在您的代码行2中:
baz || baz = 0
第一个baz
返回错误,因为没有分配这样的变量。因此,其后的作业baz = 0
未评估,但仍然是已解析,因此在接下来的上下文中,本地变量baz
已创建,并初始化为nil
。
使用第二个代码块时,foo
和true if foo
期间未分配foo
。在此之后,foo = (true if foo)
已分配给foo
,因此,即使在(true if foo)
的分配之前评估foo
,也不会在该行中引发错误。