操作/优先级的逻辑OR顺序与预期不符

时间:2016-08-24 08:50:40

标签: ruby

https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators#Logical_Or

  

二进制“或”运算符将返回其逻辑分离   两个操作数。 与“||”相同但优先级较低

据我了解,为||优先级高于“或”,下面的代码首先测试'b'是否为真,然后'c',然后如果两者都为假将测试'a'。我想见证这一点,但不确定我的理解是不正确的,还是我的测试。

a = true
b = false
c = false
p a or b || c
==> true #but were b and c checked as expected?

我试图测试这个如下..

def atest
  a = "string a"
  a.include? 'string'
  a
end

def btest
  b = "string b"
  b.include? 'string'
  b
end

def ctest
  c = "string c"
  c.include? 'string'
  c
end

puts "#{atest or btest || ctest}"
==> string a

我预计'string b'会被退回...我一周以前对编程完全不熟悉所以我不确定,我的代码是错误的还是我对引文的理解错了?

编辑:回复中似乎不鼓励欣赏,所以我会在这里隐藏它。为所有答案/进一步阅读/代码清理干杯,现在很明显我出错了。

2 个答案:

答案 0 :(得分:6)

在Ruby中,&&and||orshort-circuit operators

  

[...]仅当第一个参数不足以确定表达式的值时才执行或计算第二个参数:当AND函数的第一个参数求值为false时,总值必须为false;当OR函数的第一个参数求值为true时,总值必须为true

在你的例子中:

a or b || c

Ruby评估a,看到 truthy 值并立即返回,而不评估b || c

or优先级较低意味着表达式的计算结果为:

a or (b || c)

而不是:

(a or b) || c

就像

一样
1 + 2 * 3

评估为:

1 + (2 * 3)

因为+的优先级低于*

但它并没有改变评估的顺序。 1之前仍在评估2 * 3

另请注意,由于or的优先级非常低

p a or b || c

评估为:

(p a) or (b || c)

bc都不会以这种方式打印。

进一步阅读:

答案 1 :(得分:0)

Sidenote :在您的代码中,有些行基本上什么都不做:a.include? 'string'正在静默返回truthy,对运行的代码完全没有影响。这三个函数可能被重写为:

def atest
  "string #{__callee__[0]}"
end
alias :btest :atest
alias :ctest :atest

您将操作员优先级与正常执行流混淆。运算符优先级是指当我们将两个运算应用于同一个操作数时要提前执行的操作。否则,执行顺序是从左到右。 E.g。

a + b * c

执行为:

a
b
# oh! ambiguity: lookup the precedence table: will do multiplication
c # (otherwise a + b)
*
+