From: ale@... Date: 2002-01-07T23:08:40+09:00 Subject: Re: class name reported differently in different contexts On Mon, 7 Jan 2002, Chr. Rippel wrote: > > "Joel VanderWerf" 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