[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Is there interest in this? : get object from its object-specific class?

Rick DeNatale

3/15/2007 10:14:00 PM

The following is the culmination of a discussion on ruby-talk from a
few days ago.

Someone asked if there was a way to find the instance of a singleton
class if you only had the class. After positing a solution using
ObjectSpace.each_object, I then wrote a small extension to get it via
the hidden __attached__ instance variable.

I was then asked to submit it to ruby-core, although I'm not sure
whether it's a problem which needs to be addressed in the core.

But just in case here's the discussion. If there's interest, I could
come up with a patch for 1.8.5, 1.8.6, and maybe 1.9.

On 3/13/07, Trans <transfire@gmail.com> wrote:
>
>
> On Mar 13, 1:56 pm, "Rick DeNatale" <rick.denat...@gmail.com> wrote:
> > On 3/13/07, Trans <transf...@gmail.com> wrote:
> > Two approaches with a benchmark.
> >
> > And as I surmised, there's a really quick way to do this with a
> > relatively simple extension (at least for ruby1.8, I haven't looked at
> > this on 1.9).
> >
> > rick@frodo:/public/rubyscripts/getsinginst$ cat get_sing_inst.c
> > #include "ruby.h"
> >
> > static VALUE singleton_instance(VALUE obj)
> > {
> > if (BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) {
> > return rb_iv_get(obj, "__attached__");
> > }
> > rb_raise(rb_eTypeError, "not a singleton class");
> >
> > }
> >
> > void Init_get_sing_inst()
> > {
> > rb_define_method(rb_cClass, "singleton_instance", singleton_instance, 0);
> >
> > }
> >
> > rick@frodo:/public/rubyscripts/getsinginst$ cat gsi.rb
> > require 'get_sing_inst'
> >
> > h = {:a => 1}
> > sc = class << h
> > def foo
> > end
> >
> > self
> > end
> >
> > p sc.singleton_instance
> > p sc.singleton_instance.object_id == h.object_id
> >
> > 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
> >
> > require "benchmark"
> >
> > Benchmark.bmbm do |bm|
> > bm.report "ObjectSpace" do
> > 10000.times do instance_of_singleton_class_1(sc) end
> > end
> > bm.report "singleton_method_added" do
> > 10000.times do instance_of_singleton_class_2(sc) end
> > end
> > bm.report "primitive" do
> > 10000.times do sc.singleton_instance end
> > end
> > end
> >
> > And now for the benchmark results, note that I'm doing 10 times as
> > many interations as Trans did, 10000 vs. 1000, the primitive is on the
> > order of two orders of magnitude faster than either of the other
> > approaches.
>
> Actually, you mean Pit. He did the benchmarks. This is definitely the
> way to do it right though. I would submit this to ruby-core mailing
> list and see how it takes over there.
>
> T.
>
>
>


--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

IPMS/USA Region 12 Coordinator
http://ipmsr12.denh...

Visit the Project Mercury Wiki Site
http://www.mercuryspace...