||的奇怪含义 和|| =在Ruby中(2.0,1.9.3,jruby 1.7.4)

doo*_*ree 10 ruby jruby

从刚刚启动的会话中考虑以下irb片段:

irb:01> baz            # => NameError, baz is not defined
irb:02> baz || baz = 0 # => NameError, baz is not defined
irb:03> baz            # => nil
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

saw*_*awa 9

我不知道它是否可取,但它来自Ruby如何解析代码.只要有一段代码分配局部变量,nil即使未评估该段代码,也会分配该局部变量.在您的代码行2中:

baz || baz = 0
Run Code Online (Sandbox Code Playgroud)

第一个baz返回错误,因为没有分配这样的变量.因此baz = 0,它之后的赋值没有评估,但是它被解析了,所以在接下来的上下文中,baz创建了一个局部变量,并将其初始化为nil.

使用第二个代码块时,footrue if foo和期间不会分配foo.之后,foo = (true if foo)有一个赋值foo,所以即使在分配(true if foo)之前进行了评估foo,也不会在该行中引发错误.