Feature #4589

add Queue#each() method and include Enumerable

Added by Suraj Kurapati almost 3 years ago. Updated over 1 year ago.

[ruby-core:35828]
Status:Feedback
Priority:Normal
Assignee:Koichi Sasada
Category:lib
Target version:next minor

Description

=begin
Please add a thread-safe each() method to the Queue and SizedQueue classes
which are provided by the "thread" standard library

Also mix-in the Enumerable module into those classes so we can use map/inject/etc.

Thanks for your consideration.
=end

History

#1 Updated by Charles Nutter almost 3 years ago

=begin
At first I thought this would be a good idea. But then I realized that #each is, in every case I can think of, a non-mutating operation. Since I assume you meant for Queue#each to pop all elements off the queue, this would be the first example I know of a mutating #each.

Also, what happens when the queue is empty? Does it wait for another element, or does it end the iteration?

The behavior of #each over a queue seems fuzzy to me, and without a clear specification of what you want I don't see a path forward.
=end

#2 Updated by Eric Hodel almost 3 years ago

=begin
I don't think it is appropriate to include Enumerable. Too many methods from Enumerable seem inappropriate (or behavior would be application-specific). For example, should #find block, or only return items that match in the Queue? Should #reject remove items from the Queue, or only filter?

I can see differing needs depending on if the Queue has a single consumer or multiple consumers.
=end

#3 Updated by Suraj Kurapati over 2 years ago

Perhaps this code example can better illustrate my request:

class Queue
def each(&block)
temporarycopy = @internalqueuelock.synchronize do
@internal
itemarray.dup
end
temporary
copy.each(&block)
end
end

Charles Nutter wrote:

At first I thought this would be a good idea. But then I realized
that #each is, in every case I can think of, a non-mutating
operation.

Yes, that was my intention: read-only iteration of the queue.

Since I assume you meant for Queue#each to pop all elements off
the queue, this would be the first example I know of a mutating
#each.

Sorry if my request was unclear, but that is not what I requested.

Also, what happens when the queue is empty? Does it wait for
another element, or does it end the iteration?

It should be non-blocking. Simply iterate over the items that are
currently in the queue.

If the method was blocking, it would never finish, because we would
never reach the "end" of the queue.

The behavior of #each over a queue seems fuzzy to me, and without
a clear specification of what you want I don't see a path forward.

I hope my responses above clarify this feature request.

Eric Hodel wrote:

I don't think it is appropriate to include Enumerable. Too many
methods from Enumerable seem inappropriate (or behavior would be
application-specific). For example, should #find block, or only
return items that match in the Queue?

Since Enumerable relies on #each(), and the Queue#each method I'm
requesting is non-blocking, all of the non-destructive Enumerable
methods (like #find, #select, #map) should work as we normally
expect them to.

Should #reject remove items from the Queue, or only filter?

#reject should filter (read-only). #reject! should remove items.

I can see differing needs depending on if the Queue has a single
consumer or multiple consumers.

Hmm, shouldn't the thread-safe aspect of Queue take care of that?

#4 Updated by Eric Hodel over 2 years ago

There are no destructive methods in Enumerable.

Most times I use a Queue I am producing and consuming items at the same time so this would not be as useful for me since it works on a copy.

If I were to finish production of items or work with partial results this would be useful.

#5 Updated by Alex Young over 2 years ago

On 27/07/11 00:34, Eric Hodel wrote:

Issue #4589 has been updated by Eric Hodel.

There are no destructive methods in Enumerable.

Enumerable gets mixed into IO, and #each on a Socket is destructive
(of the buffer contents). In that sense there is precedent for this sort
of behaviour.

--
Alex

#6 Updated by Yusuke Endoh about 2 years ago

  • Status changed from Open to Assigned
  • Assignee set to Koichi Sasada

#7 Updated by Koichi Sasada over 1 year ago

  • Status changed from Assigned to Feedback
  • Target version set to next minor

Professional's comments are very welcome.
I can't determine it should be worth or not.

Also available in: Atom PDF