From f2985bd06812f183fc1382939f7844ffdb24ba50 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Fri, 24 Feb 2023 19:45:41 +0100 Subject: [PATCH] Fix Concurrent::Map default_proc arguments * Fixes https://github.com/ruby-concurrency/concurrent-ruby/issues/993 --- CHANGELOG.md | 3 +++ .../map/non_concurrent_map_backend.rb | 12 +++++++-- lib/concurrent-ruby/concurrent/version.rb | 2 +- spec/concurrent/map_spec.rb | 25 +++++++++++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a2c1c49..17a2a6415 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## Current +## Release v1.2.2 (24 Feb 2023) + +* (#993) Fix arguments passed to `Concurrent::Map`'s `default_proc`. ## Release v1.2.1 (24 Feb 2023) diff --git a/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb b/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb index fee7852ed..ca5fd9b48 100644 --- a/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +++ b/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb @@ -14,7 +14,7 @@ class NonConcurrentMapBackend # reasons. def initialize(options = nil, &default_proc) validate_options_hash!(options) if options.kind_of?(::Hash) - @backend = Hash.new(&default_proc) + set_backend(default_proc) @default_proc = default_proc end @@ -113,9 +113,17 @@ def get_or_default(key, default_value) private + def set_backend(default_proc) + if default_proc + @backend = ::Hash.new { |_h, key| default_proc.call(self, key) } + else + @backend = {} + end + end + def initialize_copy(other) super - @backend = Hash.new(&@default_proc) + set_backend(@default_proc) self end diff --git a/lib/concurrent-ruby/concurrent/version.rb b/lib/concurrent-ruby/concurrent/version.rb index 9998814ea..d1c098956 100644 --- a/lib/concurrent-ruby/concurrent/version.rb +++ b/lib/concurrent-ruby/concurrent/version.rb @@ -1,3 +1,3 @@ module Concurrent - VERSION = '1.2.1' + VERSION = '1.2.2' end diff --git a/spec/concurrent/map_spec.rb b/spec/concurrent/map_spec.rb index cfb67861d..d42f88607 100644 --- a/spec/concurrent/map_spec.rb +++ b/spec/concurrent/map_spec.rb @@ -10,6 +10,23 @@ module Concurrent @cache = described_class.new end + it 'default_proc is called with the Concurrent::Map and the key' do + map = Concurrent::Map.new do |h, k| + [h, k] + end + expect(map[:foo][0]).to be(map) + expect(map[:foo][1]).to eq(:foo) + end + + it 'default_proc is called with the Concurrent::Map and the key after #dup' do + map = Concurrent::Map.new do |h, k| + [h, k] + end + copy = map.dup + expect(copy[:foo][0]).to be(copy) + expect(copy[:foo][1]).to eq(:foo) + end + it 'concurrency' do (1..Concurrent::ThreadSafe::Test::THREADS).map do |i| in_thread do @@ -45,6 +62,14 @@ module Concurrent end describe '#compute_if_absent' do + it 'works in default_proc' do + map = Concurrent::Map.new do |map, key| + map.compute_if_absent(key) { key * 2 } + end + expect(map[3]).to eq 6 + expect(map.keys).to eq [3] + end + it 'common' do with_or_without_default_proc do expect_size_change(3) do