From: Mark Hubbart Date: 2005-05-04T15:04:34+09:00 Subject: Re: un_metaclass On 5/3/05, Ara.T.Howard@noaa.gov wrote: > On Wed, 4 May 2005, Mark Hubbart wrote: > > > On 5/3/05, Ara.T.Howard wrote: > >> > >> thoughts on how to do this > >> > >> class C > >> class << self > >> p un_metaclass #=> C > >> end > >> end > >> > >> ?? > > > > heh... I was ahead of you on that one :) in the "inside_metaclass?" > > thread, my solution returned the instance for the "true" value: > > > > http://rubytalk.org/140390 > > > > class Class > > def metaclass? > > id = inspect[/\A\#>\Z/, 1] > > ObjectSpace._id2ref(id.to_i(16)/2) if id > > end > > end > > > > Note that this code is very fragile; it will not work on 1.6.x, and > > isn't guaranteed to work in the future. It extracts the object_id of > > the instance from the metaclass' inspect string. > > it doesn't seem to work for me: > > jib:~/eg/ruby > cat a.rb > > class Module > def instance_class > m = %r/^(?:#+)$/io.match inspect > if m > klass_name, brackets = m[1], m[2] > n = brackets.size - 1 > klass = const_get klass_name > n.times{ klass = class << klass; self; end } > klass > else > superclass > end > end > def metaclass? > id = inspect[%r/\A\#>\Z/, 1] > ObjectSpace._id2ref(id.to_i(16)/2) if id > end > def both > [ instance_class, metaclass? ] > end > end > > class C > p both > class << self > p both > class << self > p both > class << self > p both > end > end > end > end > > class K < C > p both > class << self > p both > class << self > p both > class << self > p both > end > end > end > end > > jib:~/eg/ruby > ruby a.rb > [Object, nil] > [C, nil] > [#, nil] > [#>, nil] > [C, nil] > [K, nil] > [#, nil] > [#>, nil] > > did i do something wrong? Ugh. I hadn't thought about the metaclasses of classes, or the metaclasses of metaclasses of classes. The code will work for any non-class object, though, I think. I'm not sure how to do this. Some ugly hacking might make it work, but it wouldn't be correct. It can probably only be done correctly with C or DL. I hated parsing the inspect output anyway, there was something just *wrong* about that. :) cheers, Mark