void rb_extend_object(VALUE obj, VALUE module) { VALUE klass; if (TYPE(obj) == T_CLASS && RCLASS_RUBY(obj)) { VALUE sklass = rb_make_singleton_class(RCLASS_SUPER(obj)); RCLASS_SET_SUPER(obj, sklass); klass = *(VALUE *)sklass; } else { klass = rb_singleton_class(obj); } rb_include_module(klass, module); VALUE m = module; do { VALUE ary = rb_attr_get(m, idIncludedModules); if (ary != Qnil) { for (int i = 0, count = RARRAY_LEN(ary); i < count; i++) { VALUE mod = RARRAY_AT(ary, i); rb_extend_object(obj, mod); } } m = RCLASS_SUPER(m); } while (m == 0 || RCLASS_SINGLETON(m)); }
static VALUE rb_mod_append_features(VALUE module, SEL sel, VALUE include) { VALUE orig = include; switch (TYPE(include)) { case T_CLASS: case T_MODULE: break; default: Check_Type(include, T_CLASS); break; } if (RCLASS_RUBY(include)) { VALUE sinclude = rb_make_singleton_class(RCLASS_SUPER(include)); RCLASS_SET_SUPER(include, sinclude); include = sinclude; } rb_include_module2(include, orig, module, true, true); VALUE m = module; do { VALUE ary = rb_attr_get(m, idIncludedModules); if (ary != Qnil) { for (int i = 0, count = RARRAY_LEN(ary); i < count; i++) { VALUE mod = RARRAY_AT(ary, i); rb_mod_append_features(mod, sel, include); } } m = RCLASS_SUPER(m); } while (m == 0 || RCLASS_SINGLETON(m)); return module; }
VALUE rb_make_metaclass(VALUE obj, VALUE super) { VALUE klass; if (TYPE(obj) == T_CLASS && RCLASS_SINGLETON(obj)) { RBASIC(obj)->klass = rb_cClass; klass = rb_cClass; } else { VALUE objk = RBASIC(obj)->klass; if (RCLASS_SINGLETON(objk) && rb_singleton_class_attached_object(objk) == obj) { klass = objk; } else { klass = rb_make_singleton_class(super); RBASIC(obj)->klass = klass; rb_singleton_class_attached(klass, obj); } } return klass; }