Class: Enumerator

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/enumerator_comparable/initializers/enumerator_comparable.rb

Instance Method Summary collapse

Instance Method Details

#<=>(other) ⇒ Object

Stream comparison. Works only for finite sequences i.e. if both sequences are infinite, then this method never returns. If you understand dictionary order for words then you understand how this works. Shorter sequences come before longer sequences. The elements of the sequence(s) must define spaceship (<=>) too. Here’s a method that ought to be defined in Enumerator::Lazy but isn’t.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/enumerator_comparable/initializers/enumerator_comparable.rb', line 14

def <=>(other)
  loop do
    a, a_end = try_iter &:next
    b, b_end = other.try_iter &:next
    # shorter stream comes before longer (matching) stream
    result = if a_end
      if b_end
        0 # equal
      else
        -1 # I am shorter
      end
    elsif b_end
      1 # other is shorter
    else
      x = a <=> b
      x unless x == 0
    end
    next if result.nil?
    return result
  end
end

#try_iter(&block) ⇒ Object

Sometimes it is inconvenient to rescue StopIteration exceptions. This method turns that exception into a boolean value and returns it along with the next value in the sequence (if any). Useful for wrapping #peek or #next or any method or block that can raise StopIteration. For example:

val, done = try_iter &:next


42
43
44
45
46
47
48
49
50
# File 'lib/enumerator_comparable/initializers/enumerator_comparable.rb', line 42

def try_iter(&block)
  x, x_end = nil
  begin
    x = yield self
  rescue StopIteration
    x_end = true
  end
  [x,x_end]
end