In message "[ruby-talk:5239] Running two iterators in parallel"
    on 00/10/03, Dan Schmidt <dfan / harmonixmusic.com> writes:

|I have two iterators.  I would like to run them in parallel, creating
|an iterator that generates arrays containing one element from each.
|
|That is, I'd like to write 'combine' so that I can say:
|
|  def it1 ()
|    yield 1; yield 2; yield 3
|  end
|
|  def it2 ()
|    yield 4; yield 5; yield 6
|  end
|
|  combine('it1','it2') { |x|
|    # x is (1, 4), then (2, 5), then (3, 6)
|  }
|
|Some more things:
|
| - I don't want to have to modify it1 and it2 in order to write combine.
| - Ideally, combine could take an arbitrary number of iterators as
|   arguments.
| - Assume that the iterators cannot just be rewritten to provide a big
|   array all at once instead of iterating.
|
|I imagine this could be done with threads (ew).  I bet it could be
|done with continuations, but I spent a few hours last night and didn't
|get anywhere (I still have trouble understanding continuations).  Or
|maybe there's some built-in language support that I haven't found yet.
|
|Can anyone solve this puzzle?

Use threads.

  require 'thread'

  def combine(*args)
    queues = []
    for it in args
      queue = Queue.new
      Thread.start(it, queue) do |i,q|
        self.send(it) do |x|
          q.push x
        end
      end
      queues.push queue
    end
    begin
      loop do
        ary = []
        for q,th in queues
          ary.push q.pop
        end
        yield ary
      end
    rescue ThreadError
      # no more items, exit
    end
  end

-- 
							matz.