2014-02-22 65 views
1

任何人都可以解釋爲什麼這是怎麼回事?優先級``|| Ruby的`reject`阻止

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

我不知道這是什麼意思爲||具有較高的優先級,或者爲什麼它會影響到這一結果。

+2

如有疑問,請使用括號。 –

+0

使用'或'表示控制流程,'||'表示條件。是的:使用括號...... – spickermann

回答

4

答案是由於相對於不帶括號的#include?方法調用自己的優先級。

or結合更少緊緊(具有較低的優先級,即求值之後),比方法調用.include? n,所以表達式的計算結果作爲([].include? n) or (n == 1) #=> true

||,在另一方面,結合緊密(具有較高的優先級,即較早評估),因此表達式評估爲[].include?((n || (n == 1))) #=> false

優先級指的操作順序。這就像代數課,當你瞭解到PEMDAS

  • 括號,
  • 冪,
  • 乘法/除法,
  • 加法/減法。

編程語言,如數學符號,必須遵守特定的操作順序,以便非模糊地評估。在Ruby中,你這裏有業務,有云:

  • ||
  • 方法調用,
  • or
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]

+0

爲什麼人們會想要執行'n或n'?特別是'[] .include? (n或n)== 1'? –

+0

@SergioTulentsev:代碼混淆比賽? –

+1

有些情況下'n或n'可以提供有用的信息。例如,如果'n'是一個在返回「true」之前需要執行兩次嘗試的方法。 –

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該塊評估爲truen確實被拒絕。還要注意在[1]和[2] n == 1從未被執行。

因此獲得||版本的行爲像or版本只是這樣做:

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

希望這將清除的東西了。