On Mon, 7 Jan 2002, Chr. Rippel wrote:

> 
> "Joel VanderWerf" <vjoel / PATH.Berkeley.EDU> wrote in
> > class Base
> >   def Base.inherited(sub)
> >     puts "In #inherited, subclass name is #{sub}"
> >     super
> >   end
> > end
> >
> > module Mod
> >   class Sub < Base
> >     puts "In class definition, subclass name is #{self}"
> >   end
> > end
> >
> > # ==> In #inherited, subclass name is Sub
> > # ==> In class definition, subclass name is Mod::Sub
> >
> > RUBY_VERSION
> > # ==> "1.6.6"
> 
> Well in cvs you could write
> 
> ----------
> class Base
>    def Base.inherited(sub)
>      puts "In #inherited, subclass name is #{sub}"
>      super
>    end
> end
> 
> module Mod
>     Class.new Base do |klass| Mod.const_set :Sub, klass end
>     class Sub
>         puts "In class definition, subclass name is #{self}"
>    end
> end
> ----------

The tricky part here is that when the interpreter executes the row marked
with ##

  module Mod
    class Sub < Base  ##
    ...

it's going through eval.c's case NODE_CLASS (rows 3182-3233) and in there
particularly code marked by label override_class:

    ...
    override_class:
      if (!super) super = rb_cObject;
      klass = rb_define_class_id(node->nd_cname, super);
      rb_const_set(ruby_class, node->nd_cname, klass);
      ...

As you can see from the source of rb_define_class_id it first creates a
class object and then rb_funcall's superclas#inherited. After that we set
current context (ruby_class) to refer to newly created class by name got
from node->nd_cname through a call to rb_const_set.

So there's (almost) no way to know at method #inherited into which context
the class will be binded.

One way around would be to change the ruby's internal behaviour. It could
first create a class, then bind it into some constant and after that call
inherited. Then object space would be searchable to find a module which
contains the class which just inherited some other class (Ruby might be
even nice and send the context as a parameter).

The other way around would be to start a new thread in Base.inherited,
make it sleep over the rest of the initialization of the new class, and
after that do a search over the objectspace to find all the constants in
the system which refer to the class.

Anyway, it seems it's going to be tricky in either case. Sorry, couldn't
be more help this time.

     - Aleksi