And..Or..Not

顺便说一下,Ruby 有两种不同的语法来测试布尔值(true/false)条件。在上面的示例中,我使用了英文风格的运算符:andor 以及 not。如果你愿意,你可以使用类似其它语言中的一种替代运算符:&&(and)、||(or)以及 !(not)。

但是要小心,这两组运算符不是完全可以互换的。首先,它们具有不同的优先级,这意味着当在单个测试中使用多个运算符时,将会根据你使用的运算符以不同的顺序执行测试的各个部分。例如,看看这个测试:

days.rb
  1. if aDay == 'Saturday' or aDay == 'Sunday' and not working_overtime
  2. daytype = 'holiday'
  3. end

假设布尔变量 working_overtime 为 true,如果变量 aDay 用字符串 ‘Saturday’ 初始化,那么这个测试会成功吗?换句话说,如果 aDay 是 ‘Saturday’,daytype 会被赋值为 ‘holiday’ 吗?答案是:不,它不会。测试将只会在 aDay 是 ‘Saturday’ 或 ‘Sunday’,并且 working_overtime 不为 true 时成功。

思考下面这个测试:

  1. if aDay == 'Saturday' || aDay == 'Sunday' && !working_overtime
  2. daytype = 'holiday'
  3. end

从表面上看,这与上一次测试相同; 唯一的区别是这次我使用了运算符的替代语法。然而,这个变化不仅仅是表面的,因为如果 aDay 是 ‘Saturday’,那么这个测试执行结果为 true,而 daytype 则会初始化为 ‘holiday’。这是因为 || 运算符的优先级高于 or 运算符。所以这个测试会在 aDay 是 ‘Saturday’ ,或者不仅 aDay 是 ‘Sunday’ 还要 working_overtime 不为 true 时成功。

有关详细信息,请参阅本章末尾的深入挖掘部分。作为一般原则,你最好决定你喜欢哪组运算符,坚持使用它们并使用括号来避免产生歧义。