Skip to content

Commit

Permalink
Fix Map#each and #each_pair not returning enumerator outside of MRI
Browse files Browse the repository at this point in the history
When no block was passed to Map#each_pair or its alias Map#each, the
NonConcurrentMapBackend would return an enumerator, which would allow
enumerable methods to be used on a Map.

But the alternate Map backends, JRubyMapBackend and
AtomicReferenceMapBackend did not implement the same logic.

As a fix, let's move the logic down to the shared Map class, so all
implementations can use it.

Fixes #643
  • Loading branch information
ivoanjo committed Mar 29, 2017
1 parent b0e2216 commit 0bdc3c0
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
Expand Up @@ -95,7 +95,6 @@ def clear
end

def each_pair
return enum_for :each_pair unless block_given?
dupped_backend.each_pair do |k, v|
yield k, v
end
Expand Down
5 changes: 5 additions & 0 deletions lib/concurrent/map.rb
Expand Up @@ -171,6 +171,11 @@ def each_value
each_pair {|k, v| yield v}
end unless method_defined?(:each_value)

def each_pair
return enum_for :each_pair unless block_given?
super
end

alias_method :each, :each_pair unless method_defined?(:each)

def key(value)
Expand Down
16 changes: 16 additions & 0 deletions spec/concurrent/collection_each_shared.rb
Expand Up @@ -42,4 +42,20 @@
end
end
end

context 'when no block is given' do
it 'returns an enumerator' do
@cache[:a] = 1
@cache[:b] = 2

expect(@cache.send(method)).to be_a Enumerator
end

it 'returns an object which is enumerable' do
@cache[:a] = 1
@cache[:b] = 2

expect(@cache.send(method).to_a).to contain_exactly([:a, 1], [:b, 2])
end
end
end

0 comments on commit 0bdc3c0

Please sign in to comment.