void rb_include_module(VALUE klass, VALUE module) { VALUE p, c; int changed = 0; rb_frozen_class_p(klass); if (!OBJ_UNTRUSTED(klass)) { rb_secure(4); } if (TYPE(module) != T_MODULE) { Check_Type(module, T_MODULE); } OBJ_INFECT(klass, module); c = klass; while (module) { int superclass_seen = FALSE; if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module)) rb_raise(rb_eArgError, "cyclic include detected"); /* ignore if the module included already in superclasses */ for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) { switch (BUILTIN_TYPE(p)) { case T_ICLASS: if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) { if (!superclass_seen) { c = p; /* move insertion point */ } goto skip; } break; case T_CLASS: superclass_seen = TRUE; break; } } c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c)); if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries) changed = 1; skip: module = RCLASS_SUPER(module); } if (changed) rb_clear_cache(); }
void rb_include_module(VALUE klass, VALUE module) { VALUE p, c; int changed = 0; rb_frozen_class_p(klass); if (!OBJ_TAINTED(klass)) { rb_secure(4); } if (TYPE(module) != T_MODULE) { Check_Type(module, T_MODULE); } OBJ_INFECT(klass, module); c = klass; while (module) { int superclass_seen = Qfalse; if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl) rb_raise(rb_eArgError, "cyclic include detected"); /* ignore if the module included already in superclasses */ for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) { switch (BUILTIN_TYPE(p)) { case T_ICLASS: if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) { if (!superclass_seen) { c = p; /* move insertion point */ } goto skip; } break; case T_CLASS: superclass_seen = Qtrue; break; } } c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super); changed = 1; skip: module = RCLASS(module)->super; } if (changed) rb_clear_cache(); }