diff --git a/lib/concurrent/thread_safe/util/array_hash_rbx.rb b/lib/concurrent/thread_safe/util/array_hash_rbx.rb index 3fc2a38a9..52de9dacc 100644 --- a/lib/concurrent/thread_safe/util/array_hash_rbx.rb +++ b/lib/concurrent/thread_safe/util/array_hash_rbx.rb @@ -18,11 +18,22 @@ def self.allocate end klass.superclass.instance_methods(false).each do |method| - klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{method}(*args) - @_monitor.synchronize { super } - end - RUBY + case method + when :new_range, :new_reserved + klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args) + obj = super + obj.send(:_mon_initialize) + obj + end + RUBY + else + klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args) + @_monitor.synchronize { super } + end + RUBY + end end end end diff --git a/spec/concurrent/array_spec.rb b/spec/concurrent/array_spec.rb index 4dd3bbf63..7f03ab760 100644 --- a/spec/concurrent/array_spec.rb +++ b/spec/concurrent/array_spec.rb @@ -14,5 +14,15 @@ module Concurrent end end.map(&:join) end + + describe '#slice' do + # This is mostly relevant on Rubinius and Truffle + it 'correctly initializes the monitor' do + ary.concat([0, 1, 2, 3, 4, 5, 6, 7, 8]) + + sliced = ary.slice!(0..2) + expect { sliced[0] }.not_to raise_error + end + end end end