Rick said:
ObjectSpace.each_object(c2) {|o| p o}
Yeah Rick, this is what I came up with at first, too. But I didn't like
that it examines each Ruby object. Here's another solution, much
uglier but also faster:
def instance_of_singleton_class_1(sc)
ObjectSpace.each_object(sc) do |obj|
return obj
end
end
def instance_of_singleton_class_2(sc)
obj = nil
sc.class_eval do
if instance_methods(false).include?("singleton_method_added")
org = instance_method("singleton_method_added")
remove_method("singleton_method_added")
end
define_method("singleton_method_added") do |m|
obj = self
end
remove_method("singleton_method_added")
define_method("singleton_method_added", org) if org
end
obj
end
Test that they both work the same:
sc = class << {:a => 5}; self; end
p instance_of_singleton_class_1(sc) # => {:a=>5}
p instance_of_singleton_class_2(sc) # => {:a=>5}
And the benchmark:
require "benchmark"
Benchmark.bmbm do |bm|
bm.report "ObjectSpace" do
1000.times do instance_of_singleton_class_1(sc) end
end
bm.report "singleton_method_added" do
1000.times do instance_of_singleton_class_2(sc) end
end
end
yields:
Rehearsal ----------------------------------------------------------
ObjectSpace 3.109000 0.000000 3.109000 ( 3.188000)
singleton_method_added 0.266000 0.000000 0.266000 ( 0.265000)
------------------------------------------------- total: 3.375000sec
user system total real
ObjectSpace 3.016000 0.000000 3.016000 ( 3.032000)
singleton_method_added 0.266000 0.000000 0.266000 ( 0.266000)
Regards,
Pit