From: nobu.nokada@... Date: 2002-01-10T03:39:31+09:00 Subject: Re: class name reported differently in different contexts At Tue, 8 Jan 2002 17:52:09 +0900, ts wrote: > ::inherited can raise an error and the class will never exist. > > Actually ruby give a classpath to a class when it is sure that the class > will exist, before this the class not yet exist and has only a classid I guess post-init hook should be separated from self-init. And Class#inherited never be called when a new Struct is created. Index: class.c =================================================================== RCS file: /cvs/ruby/src/ruby/class.c,v retrieving revision 1.29 diff -u -2 -p -Isource -r1.29 class.c --- class.c 2002/01/07 05:27:01 1.29 +++ class.c 2002/01/09 11:45:57 @@ -143,4 +143,14 @@ rb_singleton_class_attached(klass, obj) VALUE +rb_make_metaclass(obj, klass) + VALUE obj, klass; +{ + klass = rb_singleton_class_new(klass); + RBASIC(obj)->klass = klass; + rb_singleton_class_attached(klass, obj); + return klass; +} + +VALUE rb_define_class_id(id, super) ID id; @@ -152,8 +162,5 @@ rb_define_class_id(id, super) klass = rb_class_new(super); rb_name_class(klass, id); - /* make metaclass */ - RBASIC(klass)->klass = rb_singleton_class_new(RBASIC(super)->klass); - rb_singleton_class_attached(RBASIC(klass)->klass, klass); - rb_funcall(super, rb_intern("inherited"), 1, klass); + rb_make_metaclass(klass, RBASIC(super)->klass); return klass; @@ -161,4 +168,11 @@ rb_define_class_id(id, super) VALUE +rb_class_inherited(super, klass) + VALUE super, klass; +{ + return rb_funcall(super, rb_intern("inherited"), 1, klass); +} + +VALUE rb_define_class(name, super) const char *name; @@ -180,4 +194,5 @@ rb_define_class(name, super) } klass = rb_define_class_id(id, super); + rb_class_inherited(super, klass); st_add_direct(rb_class_tbl, id, klass); @@ -206,6 +221,7 @@ rb_define_class_under(outer, name, super } klass = rb_define_class_id(id, super); - rb_const_set(outer, id, klass); rb_set_class_path(klass, outer, name); + rb_class_inherited(super, klass); + rb_const_set(outer, id, klass); return klass; @@ -654,7 +670,5 @@ rb_singleton_class(obj) } else { - klass = rb_singleton_class_new(RBASIC(obj)->klass); - RBASIC(obj)->klass = klass; - rb_singleton_class_attached(klass, obj); + klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (OBJ_TAINTED(obj)) { Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.239 diff -u -2 -p -Isource -r1.239 eval.c --- eval.c 2002/01/08 07:02:26 1.239 +++ eval.c 2002/01/09 10:20:06 @@ -3222,6 +3222,7 @@ rb_eval(self, n) if (!super) super = rb_cObject; klass = rb_define_class_id(node->nd_cname, super); - rb_const_set(ruby_class, node->nd_cname, klass); rb_set_class_path(klass,ruby_class,rb_id2name(node->nd_cname)); + rb_class_inherited(super, klass); + rb_const_set(ruby_class, node->nd_cname, klass); } if (ruby_wrapper) { Index: intern.h =================================================================== RCS file: /cvs/ruby/src/ruby/intern.h,v retrieving revision 1.75 diff -u -2 -p -Isource -r1.75 intern.h --- intern.h 2002/01/04 14:14:34 1.75 +++ intern.h 2002/01/09 11:45:37 @@ -89,4 +89,6 @@ VALUE rb_singleton_class_new _((VALUE)); VALUE rb_singleton_class_clone _((VALUE)); void rb_singleton_class_attached _((VALUE,VALUE)); +VALUE rb_make_metaclass _((VALUE, VALUE)); +VALUE rb_class_inherited _((VALUE, VALUE)); VALUE rb_define_class_id _((ID, VALUE)); VALUE rb_module_new _((void)); Index: object.c =================================================================== RCS file: /cvs/ruby/src/ruby/object.c,v retrieving revision 1.65 diff -u -2 -p -Isource -r1.65 object.c --- object.c 2002/01/04 14:14:34 1.65 +++ object.c 2002/01/09 11:49:56 @@ -625,9 +625,7 @@ rb_class_s_new(argc, argv) } klass = rb_class_new(super); - /* make metaclass */ - RBASIC(klass)->klass = rb_singleton_class_new(RBASIC(super)->klass); - rb_singleton_class_attached(RBASIC(klass)->klass, klass); + rb_make_metaclass(klass, RBASIC(super)->klass); rb_obj_call_init(klass, argc, argv); - rb_funcall(super, rb_intern("inherited"), 1, klass); + rb_class_inherited(super, klass); return klass; @@ -1130,10 +1128,7 @@ Init_Object() rb_cClass = boot_defclass("Class", rb_cModule); - metaclass = RBASIC(rb_cObject)->klass = rb_singleton_class_new(rb_cClass); - rb_singleton_class_attached(metaclass, rb_cObject); - metaclass = RBASIC(rb_cModule)->klass = rb_singleton_class_new(metaclass); - rb_singleton_class_attached(metaclass, rb_cModule); - metaclass = RBASIC(rb_cClass)->klass = rb_singleton_class_new(metaclass); - rb_singleton_class_attached(metaclass, rb_cClass); + metaclass = rb_make_metaclass(rb_cObject, rb_cClass); + metaclass = rb_make_metaclass(rb_cModule, metaclass); + metaclass = rb_make_metaclass(rb_cClass, metaclass); rb_mKernel = rb_define_module("Kernel"); Index: struct.c =================================================================== RCS file: /cvs/ruby/src/ruby/struct.c,v retrieving revision 1.28 diff -u -2 -p -Isource -r1.28 struct.c --- struct.c 2001/12/11 03:48:08 1.28 +++ struct.c 2002/01/07 18:45:28 @@ -157,4 +157,5 @@ make_struct(name, member, klass) if (NIL_P(name)) { nstr = rb_class_new(klass); + rb_class_inherited(klass, nstr); } else { -- Nobu Nakada