diff --git a/lib/weakref.rb b/lib/weakref.rb index c7274f9..8961235 100644 --- a/lib/weakref.rb +++ b/lib/weakref.rb @@ -27,24 +27,24 @@ class WeakRef < Delegator class RefError < StandardError end - @@__map = ::ObjectSpace::WeakMap.new - ## # Creates a weak reference to +orig+ def initialize(orig) case orig - when true, false, nil - @delegate_sd_obj = orig + when true, false, nil, Symbol, Integer, Float, Complex, Rational + @weak = false + @store = orig else - @@__map[self] = orig + @weak = true + @store = ::ObjectSpace::WeakMap.new + @store[self] = orig end - super end def __getobj__(&_block) # :nodoc: - @@__map[self] or defined?(@delegate_sd_obj) ? @delegate_sd_obj : - Kernel::raise(RefError, "Invalid Reference - probably recycled", Kernel::caller(2)) + return @store unless @weak + @store[self] or ::Kernel::raise(RefError, "Invalid Reference - probably recycled", ::Kernel::caller(2)) end def __setobj__(obj) # :nodoc: @@ -54,6 +54,6 @@ def __setobj__(obj) # :nodoc: # Returns true if the referenced object is still alive. def weakref_alive? - @@__map.key?(self) or defined?(@delegate_sd_obj) + !@weak || @store.key?(self) end end diff --git a/test/test_weakref.rb b/test/test_weakref.rb index f2308db..3659ec0 100644 --- a/test/test_weakref.rb +++ b/test/test_weakref.rb @@ -69,4 +69,18 @@ def test_repeated_object_memory_leak 150_000.times { WeakRef.new(a) } end; end + + if defined?(Ractor) + def test_weakref_ractor_creatable + warning = Warning[:experimental] + Warning[:experimental] = false + bug22105 = '[ruby-core:125705]' + assert_nothing_raised(Ractor::RemoteError, bug22105) do + ractor = Ractor.new { WeakRef.new(Object.new) } + Ractor.select(ractor) + end + ensure + Warning[:experimental] = warning + end + end end