Permalink
Browse files

fix a regression in rb_define_class() and rb_define_class_under(), wh…

…en checking the superclass if pre-defined classes
  • Loading branch information...
1 parent 97de43e commit c6eaf277239824b6847ad830ea4d826e3b9e96a2 Laurent Sansonetti committed Jun 28, 2011
Showing with 18 additions and 7 deletions.
  1. +18 −7 class.c
View
25 class.c
@@ -27,7 +27,8 @@ extern VALUE rb_cModuleObject;
static bool
rb_class_hidden(VALUE klass)
{
- return klass == rb_cModuleObject || klass == rb_cRubyObject || RCLASS_SINGLETON(klass);
+ return klass == rb_cModuleObject || klass == rb_cRubyObject
+ || RCLASS_SINGLETON(klass);
}
VALUE
@@ -494,6 +495,20 @@ rb_class_inherited(VALUE super, VALUE klass)
return Qnil;
}
+static void
+check_class_super(ID id, VALUE klass, VALUE super)
+{
+ VALUE k = klass;
+ do {
+ k = RCLASS_SUPER(k);
+ }
+ while (k != 0 && rb_class_hidden(k));
+
+ if (rb_class_real(k, true) != super) {
+ rb_name_error(id, "%s is already defined", rb_id2name(id));
+ }
+}
+
VALUE
rb_define_class(const char *name, VALUE super)
{
@@ -506,9 +521,7 @@ rb_define_class(const char *name, VALUE super)
if (TYPE(klass) != T_CLASS) {
rb_raise(rb_eTypeError, "%s is not a class", name);
}
- if (rb_class_real(RCLASS_SUPER(klass), true) != super) {
- rb_name_error(id, "%s is already defined", name);
- }
+ check_class_super(id, klass, super);
return klass;
}
if (!super) {
@@ -538,9 +551,7 @@ rb_define_class_under(VALUE outer, const char *name, VALUE super)
if (RCLASS_RUBY(klass)) {
// Only for pure Ruby classes, as Objective-C classes
// might be returned from the dynamic resolver.
- if (rb_class_real(RCLASS_SUPER(klass), true) != super) {
- rb_name_error(id, "%s is already defined", name);
- }
+ check_class_super(id, klass, super);
return klass;
}
}

0 comments on commit c6eaf27

Please sign in to comment.