我正在尝试评估表达式(a=10) || (rr=20)
,而未定义rr变量
所以在评估前一个表达式之前在ruby控制台中键入rr
返回
rr
NameError: undefined local variable or method `rr' for main:Object
from (irb):1
from :0
当我写表达式(a=10) || (rr=20)
时,它返回10,当我写rr后,它说nil
(a=10) || (rr=20)
rr # => nil
所以,为什么会发生这种情况?不应该只在||的第二个参数定义rr运算符是否被评估,应该永远不会基于文档?
答案 0 :(得分:11)
这是因为ruby解释器在看到变量时(但在它执行实际的代码行之前)定义了变量。您可以阅读更多相关信息in this answer。
布尔OR(||
)表达式将计算为左手表达式的值,如果它不是nil
而不是false
,则其他||
将计算为该值右手表达。
在您的示例中,ruby解释器会看到a
和rr
的分配(但它还没有执行此行),并初始化(定义,创建)a
和rr
与nil
。然后它执行||
表达式。在此||
表达式中,a
已分配给10
,并返回10
。未评估r=20
,rr
未更改(仍为nil
)。这就是为什么下一行rr
是nil
。
答案 1 :(得分:4)
正如@DOC所说,&&
和||
被称为short circuited
条件运算符。
In case of ||, if the left part of || expression returns true, the right part won't be executed.
这意味着只有当||
表达式的左侧部分返回false时才会执行正确的部分。
In case of &&, right part of the
&安培;&安培; expression will be executed only if left part of && returns true.
在给定方案(a=10) || (rr=20)
中,由于ruby表达式a=10
返回true
,因此不会执行rr = 20。请注意,在ruby赋值表达式中,除nil and false
之外返回true。
答案 2 :(得分:3)
我认为变量定义发生在解析阶段,而不是执行时刻。因此,当它评估该行时,它会解析整个事物并定义变量,但是未分配。
答案 3 :(得分:2)
当解析器发现变量时,它在其定义的上下文中自动有效。单独评估rr
无效。即使值赋值永远不会发生,评估rr=20
也足以导致定义。
这是Ruby如何尝试辨别变量和方法调用的一个怪癖。它不完美,但通常效果最好。