为什么在Ruby中,|| 当`a`未定义时,1会抛出错误,但a = a || 1会不会?
当a
未定义时,则为a || 1
a || 1
将抛出错误,但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 '' 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 '' irb(main):003:0> a = a || 1 => 1
a
在这里,您正在评估a
,这是未定义的。 因此,你得到一个例外。
a || 1
在这里,您仍然需要评估a
来确定布尔表达式的值。 如上所述, a
未定义。 因此,你得到一个例外。
a = a || 1
这里定义a
。 它被定义为未初始化的局部变量。 在Ruby中,未初始化的变量求值为nil
,因此赋值表达式的右侧求值为nil || 1
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
因为它未初始化。
当你做a || 1
a || 1
,你要求它寻找未定义的a
的值。
当你做a = a || 1
a = a || 1
你要求它寻找分配给a
似乎没有给出错误的a的值。
所以,虽然很奇怪,但我不认为它是不一致的。
你是这个意思吗?
if !(defined? a) then a = 1 end
将值声明为默认值可能更简单。