在Ruby`deject`块中使用`或`vs` ||`时的优先级

时间:2014-02-22 06:22:20

标签: ruby operator-precedence

任何人都可以解释为什么会这样吗?

[1].reject{|n| [].include? n or n == 1} # => [] 
[1].reject{|n| [].include? n || n == 1} # => [1] 

我不确定||具有更高优先级的含义,或者为什么会影响此结果。

3 个答案:

答案 0 :(得分:4)

答案是由于它们优先于没有括号的#include?方法调用。

or比方法调用.include? n紧紧绑定 less (具有更低的优先级,即稍后评估),因此表达式的计算结果为([].include? n) or (n == 1) #=> true

另一方面,

||紧紧绑定 more (具有更高的优先级,即先前评估),而不是方法调用,因此表达式的计算结果为[].include?((n || (n == 1))) #=> false

优先顺序是指操作顺序。当您学习 PEMDAS

时,就像在代数课程中一样
  • 括号,
  • 求幂,
  • 乘法/除法,
  • 加法/减法。

编程语言,如数学符号,必须遵守特定的操作顺序,以便非模糊地进行评估。在Ruby中,对于你在这里的操作,它是:

  • ||
  • 方法调用,
  • or

答案 1 :(得分:2)

确实是由于优先权和括号(希望)有助于澄清事情。

这两行是等价的:

[1] pry(main)> [1].reject{|n| [].include? n or n == 1}
=> []
[2] pry(main)> [1].reject{|n| ([].include? n) or (n == 1)}
=> []

这些是:

[3] pry(main)> [1].reject{|n| [].include? n || n == 1}
=> [1]
[4] pry(main)> [1].reject{|n| [].include? (n || n == 1)}
=> [1]

请注意,在[4]中,[].include?的参数是评估语句n || n == 1的结果,该语句返回true。由于空数组[]不包含true,因此该块的计算结果为false,而n未被拒绝。

然而,在[2]中,传递给[].include?的参数只是n。由于n等于1,因此块评估为true,而n确实被拒绝。另请注意,在[1]和[2]中n == 1从未执行过。

因此,要使||版本的行为与or版本相同,请执行以下操作:

[5] pry(main)> [1].reject{|n| ([].include? n) || (n == 1)}
=> []

希望这可以解决问题。

答案 2 :(得分:1)

[1].reject{|n| [].include? n || n == 1}

在上面的示例中,||具有更高的优先级n || n将执行,然后.include?。因此输出为[1]

[1].reject{|n| [].include? n or n == 1}

在上面的示例中,.include?将执行w.r.t n。因此输出为[]

如果您想先执行n or n,请使用:

[1].reject{|n| [].include? (n or n) == 1}

将输出[1]