为什么#Range#cover?`在比较失败时引发异常?

时间:2016-02-19 13:53:59

标签: ruby casting comparison range coerce

鉴于没有显式转换,Time对象无法与Fixnum进行比较:

0 <= Time.now # => ArgumentError: comparison of Fixnum with Time failed
Time.now <= 10000000000 # => ArgumentError: comparison of Time with 10000000000 failed

以及documentation for Range#cover?所说的内容,

  

cover?(obj)truefalse

     

如果true介于该范围的objbegin之间,则返回end

     

begin <= obj <= end exclude_end?false,而begin <= obj < endexclude_end? true时,(0...10000000000).cover?(Time.now) # => false 会对此进行测试。

我期待:

false

引发异常而非静默返回(0...10000000000).cover?(Time.now.to_i) # => true 。为什么不引发异常?

可以理解的是,通过显式转换,比较有效:

HTML DOM querySelectorAll() Method

2 个答案:

答案 0 :(得分:2)

文档没有提到实现细节。 range_cover是根据r_less(通过r_cover_p)实施的。 r_less评论说:

/* compares _a_ and _b_ and returns:
 * < 0: a < b
 * = 0: a = b
 * > 0: a > b or non-comparable
 */

以下是r_cover_p的来源:

static VALUE
r_cover_p(VALUE range, VALUE beg, VALUE end, VALUE val)
{
  if (r_less(beg, val) <= 0) {
    int excl = EXCL(range);
    if (r_less(val, end) <= -excl)
      return Qtrue;
  }
  return Qfalse;
}

正如我们所看到的,r_less次调用返回的正数会产生Qfalse

现在,我认为,医生没有提及它的原因是要保持清醒。通常情况下(99.9999%的情况),您应该比较可比较的东西,对吧?在奇怪的情况下,你没有得到正确答案(&#34;这个时间不属于这个整数范围&#34;)。

答案 1 :(得分:0)

我很确定两者。包括?和.cover?使用案例质量运算符(===),因此您获得的值与:

相同
p Time.now === 1000 #=> false