On Mon, Jul 15, 2013 at 4:24 PM, Alex Young <alex / blackkettle.org> wrote:

> I thought this sounded familiar.  It has come up before:
> http://bugs.ruby-lang.org/issues/4589
>

Hey, thanks for finding that! I figured it had probably come up before.
Some notes responding to that conversation:

- First, as Alex pointed out then, IO#each is often destructive in the
sense that it's either moving the read pointer forward or (in the case of a
pipe or socket) losing info once it advances. So there IS a precedent.
- I feel like the semantics I've implemented in the PR are moderately sane,
but feel free to point out anything I've missed.
- "Loop forever over the things coming out of this queue until something
breaks the loop" seems like a common enough use case to warrant some sugar.
- Note this is NOT "loop until the queue is exhausted", unless you turn
non_block on.
- I am explicitly not discussing the inclusion of Enumerable in this
ticket. That's a much bigger can of worms and I haven't even begun to think
through all the implications.
- Note, though, that with this PR if you DO want a full Enumerable over a
queue all you have to do now is say `q.each`, omitting the block. So we're
not making Queue enumerable, but we're making it easy to get at a queue
Enumerator if you really want one. Without this PR the shortest code I've
found to do that is:

  q = Queue.new
  eq = Enumerator.new do |y|
    loop do
      y << q.shift
    end
  end

...and this code doesn't cover all the cases that I've covered in the PR.