@foo || @foo = "bar"
在Ruby中是什么意思?对我来说,它似乎具有@foo || (@foo = "bar")
而不是(@foo || @foo) = "bar"
的含义。但是,这与||
has a higher precedence than =
in Ruby的事实相矛盾。
我知道Ruby中的||
是短路运算符。我也了解,||
将根据优先级在=
之前进行评估。我不了解的是@foo = "bar"
似乎是||
的正确操作。根据{{3}},||
的正确操作符应为@foo,并且表达式应等效于(@foo || @foo) = "bar"
,这是非法的。
答案 0 :(得分:1)
Ruby使用Short-circuit evaluation,因此它评估第一个参数以确定是否应该继续第二个参数。
在@foo || @foo = "bar"
的情况下,执行OR操作的方式是,当发现第一个参数为nil时,将评估第二个参数,这是赋值语句。如果找到第一个参数,则它将忽略第二个参数(在这种情况下为语句)
请注意,它不只是为@foo
分配值,而是在分配后完成逻辑语句的返回值。
如果您写的话,先执行@foo = @foo || 'sd'
逻辑运算然后分配。
答案 1 :(得分:1)
我想到底它确实是简单的短路评价为射线在他的回答中提到,但我认为文档是缺乏这方面。
||
是短路运算符,因此评估从左向右进行,一旦找到真,就完成评估并返回true,否则将向右进行
modifier-if
(也在链接到的页面上列出)的优先级比赋值=
低,但是赋值不是短路运算符,因此类似
foo = "not set"
is_true = false
foo = 42 if is_true
puts foo
将打印
未设置
while代码,例如:
foo = "not set"
is_true = true
foo = 42 if is_true
puts foo
将打印
42
||
是短路运算符,因此这样的代码:
foo = 0
foo || foo = 42
puts foo
将打印
0
因为左手foo不为零,所以没有理由评估右手。
而这样的代码:
foo = nil
foo || foo = 42
puts foo
将打印
42
由于foo为零,因此评估将继续在||
的右侧,直到其为true或返回最后一个表达式为true或false为止。
但是我同意您指向的文件暗示
x || y = z
应该基于优先级,可以解释为(x || y) = z
,这是不合法的。但是,很明显,这与尝试为布尔值分配值相同。
例如:
(true || true) = 42
是语法错误
与之一样:
a = nil
b = nil
(a || b) = 42
还
a = nil
b = nil
a || b = 42
puts b
结果
42
答案 2 :(得分:0)
简单来说,您对优先规则的解释是错误的。
优先规则在存在歧义时适用。使用赋值语法时,=
的左侧必须是单个标记,该标记作为常量或某种类型的变量才是合法的。
@foo || @foo = ...
只能解释为
@foo || (@foo = ...)
并且这里没有歧义,因此没有优先级问题。
优先规则所关注的是=
的右侧。就是说
@foo = bar || baz
解释为
@foo = (foo || baz)
不是
(@foo = foo) || baz