On 5/4/05, Ara.T.Howard / noaa.gov <Ara.T.Howard / noaa.gov> wrote:
> On Wed, 4 May 2005, Mark Hubbart wrote:
> 
> > 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.
> 
> the only reason i did is that i needed
> 
>    class C
>      trait 'a'
> 
>      class << self
>        trait 'a'
>      end
>    end
> 
> to behave differently and both need a handle on 'C' (sorta like superclass) to
> do so.
> 
> > 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. :)
> 
> yeah i still want a better solution.  this is what i use now:
> 
>    class Class
>      def inside_metaclass?
>        self.inspect =~ %r/^#<Class:/ ? true : false
>      end
>      def metaclass
>        if inside_metaclass?
>          self
>        else
>          class << self; self; end
>        end
>      end
>      def instance_class
>        m = %r/^(?:#<Class:)+(.*?)(>+)$/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
>    end
> 
> it's specific to my need but i'm thinking of putting together an RCR.

The problem the the above definition of inside_metaclass? is that it
will incorrectly identify and anonymous class as a metaclass:

foo = Class.new
foo.class_eval do
  puts inside_metaclass?
end

prints "true", which is wrong.

cheers,
Mark