我想了解range.cover?
如何运作,以下似乎令人困惑 -
("as".."at").cover?("ass") # true
和("as".."at").cover?("ate") # false
这个孤立的例子并不令人困惑,因为它似乎是ass
在at
之前跟ate
之前的字典样式。
("1".."z").cover?(":") # true
这个事实似乎是基于ASCII值而不是字典样式,因为在字典中我希望所有特殊字符都在数字之前,并且混乱从这里开始。如果我认为是真的那么cover?
如何决定采用哪种比较方法,即使用ASCII值或基于字典的方法。
范围如何与数组一起使用。例如 -
([1]..[10]).cover?([9,11,335]) # true
这个例子我预计是假的。但是从表面看来,在处理数组时,边界值以及cover?
的参数都会转换为字符串,而简单的字典样式比较会产生真值。这是正确的解释吗?
Range
有哪些物品需要处理?我知道它可以numbers
(复杂的除外),处理strings
,能够神秘地使用arrays
,而boolean, nil and hash
值会导致它ArgumentError: bad value for range
}
答案 0 :(得分:4)
([1]..[10]).cover?([9,11,335])
会返回true
让我们take a look at the source。在Ruby 1.9.3中,我们可以看到以下定义。
static VALUE
range_cover(VALUE range, VALUE val)
{
VALUE beg, end;
beg = RANGE_BEG(range);
end = RANGE_END(range);
if (r_le(beg, val)) {
if (EXCL(range)) {
if (r_lt(val, end))
return Qtrue;
}
else {
if (r_le(val, end))
return Qtrue;
}
}
return Qfalse;
}
如果范围的开头小于或等于给定值cover?
,则返回false
。这里小于或等于是根据r_lt
函数确定的,range_failed
函数使用<=>
运算符进行比较。让我们看看它在数组
[1] <=> [9,11,335] # => -1
显然[1]
确实小于[9,11,335]
。结果我们进入了第一个if
的主体。我们在内部检查范围是否排除其结束并再次使用<=>
运算符进行第二次比较。
[10] <=> [9,11,335] # => 1
因此[10]
大于[9,11,335]
。该方法返回true
。
ArgumentError: bad value for range
负责引发此错误的函数是RubySpec。仅在range_check
返回nil
时才会调用它。它什么时候发生?当范围的开始和结束是无法比较的(是的,再一次是我们亲爱的朋友,<=>
运营商)。
true <=> false # => nil
true
和false
无法比较。无法创建范围并引发ArgumentError
。
在结束语中,Range.cover?
对<=>
的依赖实际上是预期和记录的行为。请参阅specification of cover?
&#39; {{3}}。