Skip to content

Commit fec11e7

Browse files
committed
Conc::Map - override #inspect(), fix iteration error on MRI.
Provide custom version of Map#inspect. Hide implementation details and fix potential "insert during iteration" MRI errors.
1 parent 9bd16bb commit fec11e7

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

lib/concurrent/map.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,15 @@ def marshal_load(hash)
202202

203203
undef :freeze
204204

205+
# @!visibility private
206+
DEFAULT_OBJ_ID_STR_WIDTH = (2**50).class == Fixnum ? 14 : 7 # we want to look "native", 7 for 32-bit, 14 for 64-bit
207+
# override default #inspect() method: firstly, we don't want to be spilling our guts (i-vars), secondly, MRI backend's
208+
# #inspect() call on its @backend i-var will bump @backend's iter level while possibly yielding GVL
209+
def inspect
210+
id_str = (object_id << 1).to_s(16).rjust(DEFAULT_OBJ_ID_STR_WIDTH, '0')
211+
"#<#{self.class.name}:0x#{id_str} entries=#{size} default_proc=#{@default_proc.inspect}>"
212+
end
213+
205214
private
206215
def raise_fetch_no_key
207216
raise KeyError, 'key not found'

spec/concurrent/map_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,15 @@ def key # assert_collision_resistance expects to be able to call .key to get the
826826
expect { Marshal.dump(Concurrent::Map.new {}) }.to raise_error(TypeError)
827827
end
828828

829+
it '#inspect' do
830+
regexp = /\A#<Concurrent::Map:0x[0-9a-f]+ entries=[0-9]+ default_proc=.*>\Z/i
831+
expect(Concurrent::Map.new.inspect).to match(regexp)
832+
expect((Concurrent::Map.new {}).inspect).to match(regexp)
833+
map = Concurrent::Map.new
834+
map[:foo] = :bar
835+
expect(map.inspect).to match(regexp)
836+
end
837+
829838
private
830839

831840
def with_or_without_default_proc(&block)

0 commit comments

Comments
 (0)