void rb_alias(VALUE klass, ID name, ID def) { VALUE target_klass = klass; rb_method_entry_t *orig_me; rb_method_flag_t flag = NOEX_UNDEF; if (NIL_P(klass)) { rb_raise(rb_eTypeError, "no class to make alias"); } rb_frozen_class_p(klass); if (klass == rb_cObject) { rb_secure(4); } again: orig_me = search_method(klass, def); if (UNDEFINED_METHOD_ENTRY_P(orig_me)) { if ((!RB_TYPE_P(klass, T_MODULE)) || (orig_me = search_method(rb_cObject, def), UNDEFINED_METHOD_ENTRY_P(orig_me))) { rb_print_undef(klass, def, 0); } } if (orig_me->def->type == VM_METHOD_TYPE_ZSUPER) { klass = RCLASS_SUPER(klass); def = orig_me->def->original_id; flag = orig_me->flag; goto again; } if (flag == NOEX_UNDEF) flag = orig_me->flag; rb_method_entry_set(target_klass, name, orig_me, flag); }
static int clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data) { VALUE newiseqval; if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) { rb_iseq_t *iseq; newiseqval = rb_iseq_clone(me->def->body.iseq->self, data->klass); GetISeqPtr(newiseqval, iseq); rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); RB_GC_GUARD(newiseqval); } else { rb_method_entry_set(data->klass, mid, me, me->flag); } return ST_CONTINUE; }
static void clone_method(VALUE klass, ID mid, const rb_method_entry_t *me) { VALUE newiseqval; if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) { rb_iseq_t *iseq; newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass); GetISeqPtr(newiseqval, iseq); OBJ_WRITE(iseq->self, &iseq->cref_stack, rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass)); rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); RB_GC_GUARD(newiseqval); } else { rb_method_entry_set(klass, mid, me, me->flag); } }
static VALUE rb_mod_modfunc(int argc, VALUE *argv, VALUE module) { int i; ID id; const rb_method_entry_t *me; if (!RB_TYPE_P(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_method_entry_set(rb_singleton_class(module), id, me, NOEX_PUBLIC); } return module; }