Module: Bible::BibleRefParser::RangeComparisons

Included in:
Chapters, Verses
Defined in:
lib/bible/parser.rb

Overview

Helper module which can is used by Verses and Chapters objects to compare themselves against Arrays and Ranges.

Instance Method Summary collapse

Instance Method Details

#compare_ranges(ranges, value, which) ⇒ Object

Compares the given ranges to the given value. value can hold an Array or a Range. An array can contain fixnums or ranges.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/bible/parser.rb', line 146

def compare_ranges(ranges, value, which)
  return (value.empty? && ranges.empty?) if value.is_a?(Array) && (value.empty? || ranges.empty?)
  return (value.nil? && ranges.empty?) if value.nil? || ranges.empty?

  if value.is_a?(Range)
    # Continuous ranges mean there are no nil elements in the array, since those represent
    # discontinuous verses or chapters. Therefore, first step is to make sure ranges holds all non-nil items.
    raise "Can't compare to range because #{which} are not continuous." unless ranges.nitems == ranges.length
    return Range.new(ranges.first, ranges.last) == value
  elsif value.is_a?(Array)
    # compare all non-nil elements, since nils are just internal markers for our use
    c = ranges.compact
    offset = 0
    value.each_with_index do |val, idx|
      if val.is_a?(Range)
        val.each do |range_value|
          return false if range_value != c[idx + offset]
          offset += 1
        end
        offset -= 1
      else
        return false if val != c[idx + offset]
      end
    end
    return true
  elsif value.respond_to?(:to_i)
    raise "Can't compare single fixnum to multiple #{which}." unless ranges.length == 1
    return ranges[0].to_i == value.to_i
  else
    raise "Don't know how to compare #{which} to value #{value.inspect}"
  end
  
end