奇怪的Ruby如果声明问题

时间:2010-09-24 00:55:03

标签: ruby

我注意到Ruby中的If Statements中有点奇怪(我认为)。这是一个例子:

my_number = nil
if my_number < 3
   'number is less than 3'
end

显然,当您运行此代码时,您将获得“Fixnum与nil失败的比较”错误。现在这里有点奇怪。如果我在If语句中进行一点改动以检查nil,它可以正常工作。例如:

my_number = nil
if my_number && my_number < 3
   'number is less than 3'
end

添加nil检查使其不会崩溃。这听起来可能都很愚蠢,但我无法弄清楚为什么会有效。它不应该仍然会出错吗?

感谢任何能够解释这一点的人。 :)谢谢!

5 个答案:

答案 0 :(得分:4)

布尔表达式以所谓的“短路”方式进行评估。也就是说,只要它知道结果,它就不会继续尝试评估表达式。

所以if my_numberfalse一样,所以没有必要继续,因为false && <anything>总是假的。

这是一个有用的语言功能,许多语言都是这样工作的(原始的Visual Basic是我能想到的一个例外),因为它可以让你完成这种测试而不需要繁琐的嵌套'if'。

答案 1 :(得分:1)

这不是特定于Ruby的方式:我已经注意到了我曾经使用的所有语言中的这种行为,从Pascal到Java。

如果你有布尔表达式b1 && b2 && b3 ... && bn,大多数语言保证从左到右评估bi,如果某些bi结果是false,评估将会停下来(因为整个表达式都是假的)。与布尔||运算符相同。

答案 2 :(得分:0)

测试nil必须可以,所以if nil或类似的东西几乎适用于所有语言。

但是对于算术比较,如果它没有抛出异常,则必须返回true或false。无论哪种方式都存在问题。

真实的没有意义,因为nil将是&lt;和&gt;比3。

虚假几乎一样糟糕,因为现在nil < 3nil >= 3都是假的,这并不理想。

因此,比较方法会抛出异常。问题解决了。

答案 3 :(得分:0)

nil是“falsy”。在irb中试试这个:

irb(main):001:0> puts "Nil is true " if nil
=> nil
irb(main):002:0> puts "Nil is not true " if !nil
Nil is not true
=> nil

nil与false不同,但是它在循环和其他测试中对它有很大的帮助:

false == nil
=> false

因为你的第一部分和假红宝石做了懒惰的事情,甚至懒得评估下一个比特,如果它是&gt; 3。

答案 4 :(得分:0)

正在发生的事情称为短路评估。你的陈述可以这样想:

if( my_number )
  if( my_number < 3)
    'number is less than 3'
  end
end

由于第一个条件为假,因此没有理由评估该语句的第二个条件 - my_number&lt; 3部分。