Class: Range

Inherits:
Object show all
Defined in:
lib/backports/2.0.0/range/size.rb,
lib/backports/2.6.0/range/cover.rb,
lib/backports/2.0.0/range/bsearch.rb,
lib/backports/3.3.0/range/overlap.rb,
lib/backports/3.3.0/range/reverse_each.rb

Instance Method Summary collapse

Instance Method Details

#bsearchObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/backports/2.0.0/range/bsearch.rb', line 5

def bsearch
  return to_enum(:bsearch) unless block_given?
  from = self.begin
  to   = self.end
  unless from.is_a?(Numeric) && to.is_a?(Numeric)
    raise TypeError, "can't do binary search for #{from.class}"
  end

  midpoint = nil
  if from.is_a?(Integer) && to.is_a?(Integer)
    convert = Proc.new{ midpoint }
  else
    from = Backports.float_to_integer(from.to_f)
    to   = Backports.float_to_integer(to.to_f)
    convert = Proc.new{ Backport.integer_to_float(midpoint) }
  end
  to -= 1 if exclude_end?
  satisfied = nil
  while from <= to do
    midpoint = (from + to).div(2)
    result = yield(cur = convert.call)
    case result
    when Numeric
      return cur if result == 0
      result = result < 0
    when true
      satisfied = cur
    when nil, false
      # nothing to do
    else
      raise TypeError, "wrong argument type #{result.class} (must be numeric, true, false or nil)"
    end

    if result
      to = midpoint - 1
    else
      from = midpoint + 1
    end
  end
  satisfied
end

#cover_with_range_compatibility?(what) ⇒ Boolean

Returns:

  • (Boolean)


5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/backports/2.6.0/range/cover.rb', line 5

def cover_with_range_compatibility?(what)
  return cover_without_range_compatibility?(what) unless what.is_a?(Range)

  left = self.begin <=> what.begin
  right = self.end <=> what.end
  return false unless left && right

  left <= 0 && (
    right >= 1 ||
    right == 0 && (!exclude_end? || what.exclude_end?) ||
    what.exclude_end? && what.begin.is_a?(Integer) &&
      what.end.is_a?(Integer) && cover_without_range_compatibility?(what.end - 1)
  )
end

#overlap?(other) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (TypeError)


3
4
5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/backports/3.3.0/range/overlap.rb', line 3

def overlap?(other)
  raise TypeError, "wrong argument type #{other.class} (expected Range)" unless other.is_a?(Range)

  [
    [other.begin, self.end, exclude_end?],
    [self.begin, other.end, other.exclude_end?],
    [self.begin, self.end, exclude_end?],
    [other.begin, other.end, other.exclude_end?],
  ].all? do |from, to, excl|
    less = (from || -Float::INFINITY) <=> (to || Float::INFINITY)
    less = +1 if less == 0 && excl
    less && less <= 0
  end
end

#reverse_each_with_endless_handling(&block) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/backports/3.3.0/range/reverse_each.rb', line 5

def reverse_each_with_endless_handling(&block)
  case self.end
  when nil
    raise "Hey"
  when Float::INFINITY
    raise "Hey"
  when Integer
    delta = exclusive? ? 1 : 0
    ((self.end - delta)..(self.begin)).each(&block)
  else
    reverse_each_without_endless_handling(&block)
  end
end

#sizeObject



5
6
7
8
9
10
11
12
13
14
15
# File 'lib/backports/2.0.0/range/size.rb', line 5

def size
  return nil unless self.begin.is_a?(Numeric) && self.end.is_a?(Numeric)
  size = self.end - self.begin
  return 0 if size <= 0
  return size if size == Float::INFINITY
  if exclude_end?
    size.ceil
  else
    size.floor + 1
  end
end