为什么在Ruby中,|| 当`a`未定义时,1会抛出错误,但a = a || 1会不会?

nop*_*ole 7 ruby exception undefined undefined-behavior

何时a未定义,a || 1则会抛出错误,但a = a || 1不会.这有点不一致吗?

irb(main):001:0> a
NameError: undefined local variable or method 'a' for main:Object
        from (irb):1
        from c:/ruby/bin/irb:12:in '<main>'

irb(main):002:0> a || 1
NameError: undefined local variable or method 'a' for main:Object
        from (irb):2
        from c:/ruby/bin/irb:12:in '<main>'

irb(main):003:0> a = a || 1
=> 1
Run Code Online (Sandbox Code Playgroud)

Jör*_*tag 9

a
Run Code Online (Sandbox Code Playgroud)

在这里,您正在评估a,未定义.因此,你得到一个例外.

a || 1
Run Code Online (Sandbox Code Playgroud)

在这里,您仍然需要评估a以确定布尔表达式的值.就像上面一样,a没有定义.因此,你得到一个例外.

a = a || 1
Run Code Online (Sandbox Code Playgroud)

在这里,a 定义.它被定义为未初始化的局部变量.在Ruby中,未初始化的变量求值为nil,因此赋值表达式的右侧计算为nil || 1哪个求1值,因此赋值表达式的返回值是1,并且副作用a是初始化为1.

编辑:似乎在变量定义时以及在Ruby中初始化时存在一些混淆.get在解析时定义,但在运行时初始化.你可以在这里看到它:

 foo # => NameError: undefined local variable or method `foo' for main:Object
Run Code Online (Sandbox Code Playgroud)

foo 未定义.

if false
  foo = 'This will never get executed'
end
Run Code Online (Sandbox Code Playgroud)

此时foo,即使该行永远不会执行,也会定义.线永远不会被执行的事实完全无关紧要,因为解释器无论如何都与此无关:局部变量由解析器定义,解析器显然看到这一行.

foo # => nil
Run Code Online (Sandbox Code Playgroud)

没有错误,因为foo已定义,并且它的计算结果是nil因为它未初始化.