1. or ||

    这些运算符只有在判断左侧结果为 false 时,会继续判断右侧,or 的优先级比 || 低。

    1. not !

    布尔值的否操作,即值为 false 时返回 true,值为 true 时返回 false。

    使用两种不同的布尔运算符时要小心。由于优先级的差异,测试将以不同的顺序进行判断,并可能产生不同的结果。

    思考以下代码:

    boolean_ops.rb
    1. # Example 1
    2. if (1==3) and (2==1) || (3==3) then
    3. puts('true')
    4. else
    5. puts('false')
    6. end
    7. # Example 2
    8. if (1==3) and (2==1) or (3==3) then
    9. puts('true')
    10. else
    11. puts('false')
    12. end

    现在来看示例 2,其测试是:(如果 1 等于 3 ,并且 2 等于 1)[false],或者 3 等于 3 [true]。这次,我们仅需要两个测试中一个成功即可;第二个测试判断为 true,所以整个测试返回 true 。

    在这样的测试中,运算符优先级的副作用可能会导致非常模糊的错误。你可以通过使用括号来清楚的表达测试的含义来避免这些错误。在这里,我重写了上面的示例 1 和 2;在每种情况下,添加一对括号都会反转测试返回的布尔值:

    否定运算符 ! 可以在表达式的开头使用,或者你可以在一个表达的左侧和右侧中间使用 !=(不等于)运算符:

    1. !(1==1) #=> false
    2. 1 != 1 #=> false

    或者,你可以用 not 代替 !

    1. not(1==1)
    eccentricities.rb
    1. puts( not( 1==1 ) ) # This is a syntax error
    2. puts( true && true && !(true) ) # This is ok
    3. puts( ((true) and (true)) ) # This is ok
    4. puts( true && true ) # This is ok
    5. puts( true and true ) # This is a syntax error

    在多数情况下,可以通过统一使用同一类型的运算符(要么用 andornot,要么用 &&||!)来避免这些问题,而不是混合地使用两者。另外,推荐经常使用括号。

    Ruby 提供了一对方法 catchthrow,可用于在满足某些条件时中断(break)代码块的执行。这是 Ruby 中与其它一些编程语言中的 goto 最接近的等价语法。该代码块必须以 catch 后跟一个符号(symbol)(即以冒号开头的唯一标识符)开头,例如 :done:finished。代码块本身可以用大括号限定,也可以用关键字 doend 限定,如下所示:

    在块内,你可以使用一个符号(symbol)作为参数调用 throw。通常,当满足某些特定条件时,你将可以调用 throw 来跳过块中的所有剩余的未执行代码。例如,让我们假设该块包含这样一些代码,提示用户输入一个数字,用某个值来除以该数字,然后继续对结果进行大量其它的复杂计算。显然,如果用户输入 0,则后面的计算都不能完成,因此你可以通过跳出块来跳过这些计算,并继续执行块后的任何代码。这是这样做的一种方式:

    catch_throw.rb
    1. catch(:finished) do
    2. print('Enter a number: ')
    3. num = gets().chomp.to_i
    4. if num == 0 then
    5. throw :finished # if num is 0, jump out of the block
    6. end
    7. # Here there may be hundreds of lines of
    8. # calculations based on the value of num
    9. # if num is 0 this code will be skipped
    10. end
    11. # jump to here – outside of the block
    12. puts("Finished")

    实际上,你可以在块外面调用 throw,像这样:

    1. i = 0
    2. while true
    3. puts("I'm doing things...")
    4. i += 1
    5. throw(:go_for_tea) if (i == aNum)
    6. # throws to end of go_to_tea block
    7. end
    8. end
    9. catch(:go_for_tea) { # this is the :go_to_tea block
    10. dothings(5)
    11. }
    1. catch(:finished) do
    2. print('Enter a number: ')
    3. num = gets().chomp.to_i
    4. if num == 0 then throw :finished end
    5. puts( 100 / num )
    6. catch(:go_for_tea) {
    7. dothings(5)
    8. }
    9. end

    与其它编程语言中的 gotos 和 jumps 一样,在 Ruby 应该非常谨慎地使用 和 throw,因为它们会破坏代码的逻辑,并且可能会引入难以发现的错误。