diff --git a/lib/delegate.rb b/lib/delegate.rb index 838de67..b5224ea 100644 --- a/lib/delegate.rb +++ b/lib/delegate.rb @@ -345,10 +345,16 @@ def __setobj__(obj) end def Delegator.delegating_block(mid) # :nodoc: - lambda do |*args, &block| + prok = lambda do |*args, &block| target = self.__getobj__ target.__send__(mid, *args, &block) - end.ruby2_keywords + end + prok.ruby2_keywords + if defined?(Ractor.shareable_proc) + Ractor.shareable_proc(&prok) + else + prok + end end # diff --git a/test/test_delegate.rb b/test/test_delegate.rb index ff7998e..ca170e3 100644 --- a/test/test_delegate.rb +++ b/test/test_delegate.rb @@ -390,4 +390,20 @@ def test(a, k:) [a, k]; end a = DelegateClass(k).new(k.new) assert_equal([1, 0], a.test(1, k: 0)) end + + def test_delegate_class_can_be_used_in_ractors + omit "no Ractor#value" unless defined?(Ractor) && Ractor.method_defined?(:value) + require_path = File.expand_path(File.join(__dir__, "..", "lib", "delegate.rb")) + raise "file doesn't exist: #{require_path}" unless File.exist?(require_path) + assert_ractor <<-RUBY + require "#{require_path}" + class MyClass < DelegateClass(Array);end + values = 2.times.map do + Ractor.new do + MyClass.new([1,2,3]).at(0) + end + end.map(&:value) + assert_equal [1,1], values + RUBY + end end