# This is an example collection demonstrating the difference between
# external iterators and internal iterators.

class Pair

  attr_accessor :first, :last

  def initialize(first = nil, last = nil)
    @first = first
    @last = last
  end

  # The internal iterator is an instance method
  def each
    yield first
    yield last
  end

  # The external iterator is a full-blown, separate class
  # which also wants an instance method to obtain an
  # iterator instance

  def iterator
    Iterator.new(self)
  end

  # Wow, this iterator's definition is longer than the
  # collection's!
  class Iterator
    def initialize(pair)
      @pair = pair
      @next = :first
    end
    def has_next?
      @next.nil?
    end
    def next
      case @next
      when :first
        @next = :last
        first
      when :last
        @next = nil
        last
      else
        fail
      end
    end
  end
end

col = Pair.new "a", "b"

# Internal iterator: just pass the block to the iterator
col.each do |x|
  print x
end

# External iterator: instantiate, check, fetch
iter = col.iterator
while iter.has_next?
  x = iter.next
  print x
end

