Project

General

Profile

Feature #4168 » show_bug.rb

Script to reproduce the bug - bdurand (Brian Durand), 12/18/2010 01:57 AM

 
require 'weakref'

def test_weak_references(klass, iterations)
puts "Testing if object id's can be reused by #{klass}..."
i = 0
n = 0
id_to_ref = {}
failures = 0
iterations = 100000 if iterations <= 0
iterations.times do
i += 1
obj = Object.new

if id_to_ref.key?(obj.object_id)
n += 1
ref = id_to_ref[obj.object_id]
if ref.weakref_alive?
STDOUT.write('x')
STDOUT.flush
failures += 1
end
end

ref = klass.new(obj)
id_to_ref[obj.object_id] = ref
raise "#{klass} did not return the correct object!" unless (klass.name == "WeakReference" ? ref.object : ref.__getobj__) == obj
if i % 5000 == 0
STDOUT.write('.')
STDOUT.flush
end
end
STDOUT.write("\n")
collected = n
id_to_ref.values.each do |ref|
collected += 1 if ref.weakref_alive?
end
puts "#{collected} instances out of #{iterations} (#{((collected.to_f / iterations) * 100).round}%) objects refererenced by #{klass} were reclaimed by the garbage collector"
if failures == 0
puts "SUCCESS: even with #{n} object id's being reused in #{iterations} iterations"
else
puts "FAILURE: #{failures} instances of object ids being incorrectly referenced in #{iterations} iterations"
end
end

if $0 == __FILE__
iterations = ARGV.first.to_i
if defined?(WeakReference)
# Compatibilty hack to make WeakReference duck type like a WeakRef for the test.
module WeakRefCompatibility
def __getobj__
object
end
def weakref_alive?
object != nil
end
end
WeakReference.send(:include, WeakRefCompatibility)
test_weak_references WeakReference, iterations
end
test_weak_references WeakRef, iterations
end
(3-3/9)