static int clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data) { switch (me->type) { case VM_METHOD_TYPE_ISEQ: { VALUE newiseqval = rb_iseq_clone(me->body.iseq->self, data->klass); rb_iseq_t *iseq; GetISeqPtr(newiseqval, iseq); rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); break; } default: rb_add_method_me(data->klass, mid, me, me->flag); break; } return ST_CONTINUE; }
static VALUE rb_mod_modfunc(int argc, VALUE *argv, VALUE module) { int i; ID id; const rb_method_entry_t *me; if (TYPE(module) != T_MODULE) { rb_raise(rb_eTypeError, "module_function must be called for modules"); } secure_visibility(module); if (argc == 0) { SCOPE_SET(NOEX_MODFUNC); return module; } set_method_visibility(module, argc, argv, NOEX_PRIVATE); for (i = 0; i < argc; i++) { VALUE m = module; id = rb_to_id(argv[i]); for (;;) { me = search_method(m, id); if (me == 0) { me = search_method(rb_cObject, id); } if (UNDEFINED_METHOD_ENTRY_P(me)) { rb_print_undef(module, id, 0); } if (me->def->type != VM_METHOD_TYPE_ZSUPER) { break; /* normal case: need not to follow 'super' link */ } m = RCLASS_SUPER(m); if (!m) break; } rb_add_method_me(rb_singleton_class(module), id, me, NOEX_PUBLIC); } return module; }
void rb_alias(VALUE klass, ID name, ID def) { rb_method_entry_t *orig_me; rb_frozen_class_p(klass); if (klass == rb_cObject) { rb_secure(4); } orig_me = search_method(klass, def); if (UNDEFINED_METHOD_ENTRY_P(orig_me)) { if ((TYPE(klass) != T_MODULE) || (orig_me = search_method(rb_cObject, def), UNDEFINED_METHOD_ENTRY_P(orig_me))) { rb_print_undef(klass, def, 0); } } rb_add_method_me(klass, name, orig_me, orig_me->flag); }