Module: RangeWithGaps::RangeMath

Included in:
Range, RangeWithMath
Defined in:
lib/range_with_gaps/range_math.rb

Instance Method Summary collapse

Instance Method Details

#&(enum) ⇒ Object

Returns a new range containing all elements that are common to both.



14
15
16
17
18
19
20
21
22
# File 'lib/range_with_gaps/range_math.rb', line 14

def &(enum)
  enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  return nil unless overlap?(enum)

  first_val = [first, enum.first].max
  hi = lower_or_equal_rhs_as?(enum) ? self : enum

  self.class.new first_val, hi.last, hi.exclude_end?
end

#-(enum) ⇒ Object

Returns a new range by subtracting the given range from self. If all elements are removed then returns nil. If the subtracting range results in a split of self then we return two ranges in a sorted array. Only works on ranges that represent a sequence of values and respond to succ.



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/range_with_gaps/range_math.rb', line 47

def -(enum)
  return self.dup unless overlap?(enum)

  if enum.mask?(self)
    nil
  elsif first >= enum.first
    ltrim enum
  elsif lower_or_equal_rhs_as?(enum)
    rtrim enum
  else
    [rtrim(enum), ltrim(enum)]
  end
end

#adjacent?(enum) ⇒ Boolean

Return true if this range and the other range are adjacent to each other. Non-sequential ranges that exclude an end can not be adjacent.

Returns:

  • (Boolean)


39
40
41
# File 'lib/range_with_gaps/range_math.rb', line 39

def adjacent?(enum)
  adjacent_before?(enum) || enum.adjacent_before?(self)
end

#empty?Boolean

Returns true if this range has nothing. This only happens with ranges such as (0…0)

Returns:

  • (Boolean)


71
72
73
# File 'lib/range_with_gaps/range_math.rb', line 71

def empty?
  last == first && exclude_end?
end

#mask?(enum) ⇒ Boolean

Returns true if this range completely covers the given range.

Returns:

  • (Boolean)


9
10
11
# File 'lib/range_with_gaps/range_math.rb', line 9

def mask?(enum)
  higher_or_equal_rhs_as?(enum) && include?(enum.first)
end

#overlap?(enum) ⇒ Boolean

From Ruby Facets. Returns true if this range overlaps with another range.

Returns:

  • (Boolean)


4
5
6
# File 'lib/range_with_gaps/range_math.rb', line 4

def overlap?(enum)
  include?(enum.first) or enum.include?(first)
end

#sizeObject

Return the physical dimension of the range. Only works with ranges that represent a sequence. This can be confusing for ranges of floats, since (0.0..42.0) will result in the same size as (0.0…42.0). Won’t work with ranges that don’t support the minus operator.



65
66
67
# File 'lib/range_with_gaps/range_math.rb', line 65

def size
  (sequential? ? one_after_max : last) - first
end

#|(enum) ⇒ Object

Returns a new range built by merging self and the given range. If they are non-overlapping then we return an array of ranges.



26
27
28
29
30
31
32
33
34
35
# File 'lib/range_with_gaps/range_math.rb', line 26

def |(enum)
  if overlap?(enum) || adjacent?(enum)
    first_val = [first, enum.first].min
    hi = higher_or_equal_rhs_as?(enum) ? self : enum

    self.class.new first_val, hi.last, hi.exclude_end?
  else
    return self, enum
  end
end