7

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
4

3 回答 3

9
a

在这里,您正在评估a未定义的 。因此,您会遇到异常。

a || 1

在这里,您仍然需要评估a以确定布尔表达式的值。就像上面一样,a没有定义。因此,您会遇到异常。

a = a || 1

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

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

 foo # => NameError: undefined local variable or method `foo' for main:Object

foo未定义。

if false
  foo = 'This will never get executed'
end

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

foo # => nil

没有错误,因为foo已定义,它评估为nil因为它未初始化。

于 2010-06-06T09:12:57.823 回答
1

当您这样做时a || 1,您是在要求它查找a未定义的值。

当您这样做时,a = a || 1您要求它查找分配aawhich 似乎没有给出错误的值。

所以,虽然很奇怪,但我不认为它是不一致的。

于 2010-06-06T07:08:18.763 回答
0

你是这个意思吗?

if !(defined? a) then
    a = 1
end

将值声明为 1 作为默认值可能更简单。

于 2010-06-06T07:11:16.247 回答