Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
Range#overlap?
static VALUE
range_overlap(VALUE range, VALUE other)
{
if (!rb_obj_is_kind_of(other, rb_cRange)) {
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Range)",
rb_class_name(rb_obj_class(other)));
}
VALUE self_beg = RANGE_BEG(range);
VALUE self_end = RANGE_END(range);
int self_excl = EXCL(range);
VALUE other_beg = RANGE_BEG(other);
VALUE other_end = RANGE_END(other);
int other_excl = EXCL(other);
if (empty_region_p(self_beg, other_end, other_excl)) return Qfalse;
if (empty_region_p(other_beg, self_end, self_excl)) return Qfalse;
if (!NIL_P(self_beg) && !NIL_P(other_beg)) {
VALUE cmp = rb_funcall(self_beg, id_cmp, 1, other_beg);
if (NIL_P(cmp)) return Qfalse;
/* if both begin values are equal, no more comparisons needed */
if (rb_cmpint(cmp, self_beg, other_beg) == 0) return Qtrue;
}
else if (NIL_P(self_beg) && !NIL_P(self_end) && NIL_P(other_beg) && !NIL_P(other_end)) {
VALUE cmp = rb_funcall(self_end, id_cmp, 1, other_end);
return RBOOL(!NIL_P(cmp));
}
if (empty_region_p(self_beg, self_end, self_excl)) return Qfalse;
if (empty_region_p(other_beg, other_end, other_excl)) return Qfalse;
return Qtrue;
}
Returns true if range overlaps with self, false otherwise:
(0..2).overlap?(1..3) #=> true (0..2).overlap?(3..4) #=> false (0..).overlap?(..0) #=> true
With non-range argument, raises TypeError.
(1..3).overlap?(1) # TypeError
Returns false if an internal call to <=> returns nil; that is, the operands are not comparable.
(1..3).overlap?('a'..'d') # => false
Returns false if self or range is empty. “Empty range” means that its begin value is larger than, or equal for an exclusive range, its end value.
(4..1).overlap?(2..3) # => false (4..1).overlap?(..3) # => false (4..1).overlap?(2..) # => false (2...2).overlap?(1..2) # => false (1..4).overlap?(3..2) # => false (..4).overlap?(3..2) # => false (1..).overlap?(3..2) # => false (1..2).overlap?(2...2) # => false
Returns false if the begin value one of self and range is larger than, or equal if the other is an exclusive range, the end value of the other:
(4..5).overlap?(2..3) # => false (4..5).overlap?(2...4) # => false (1..2).overlap?(3..4) # => false (1...3).overlap?(3..4) # => false
Returns false if the end value one of self and range is larger than, or equal for an exclusive range, the end value of the other:
(4..5).overlap?(2..3) # => false (4..5).overlap?(2...4) # => false (1..2).overlap?(3..4) # => false (1...3).overlap?(3..4) # => false
Note that the method wouldn’t make any assumptions about the beginless range being actually empty, even if its upper bound is the minimum possible value of its type, so all this would return true:
(...-Float::INFINITY).overlap?(...-Float::INFINITY) # => true (..."").overlap?(..."") # => true (...[]).overlap?(...[]) # => true
Even if those ranges are effectively empty (no number can be smaller than -Float::INFINITY), they are still considered overlapping with themselves.
Related: Range#cover?.
Ruby version changes
-
4.0
-
Range#overlap?now correctly handles infinite (unbounded) ranges. [Bug #21185]
-
-
3.3
-
Range#overlap?added for checking if two ranges overlap. [Feature #19839]
-