static void remove_method(VALUE klass, ID mid) { st_data_t key, data; rb_method_entry_t *me = 0; if (klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't remove method"); } rb_check_frozen(klass); if (mid == object_id || mid == id__send__ || mid == idInitialize) { rb_warn("removing `%s' may cause serious problems", rb_id2name(mid)); } if (!st_lookup(RCLASS_M_TBL(klass), mid, &data) || !(me = (rb_method_entry_t *)data) || (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF)) { rb_name_error(mid, "method `%s' not defined in %s", rb_id2name(mid), rb_class2name(klass)); } key = (st_data_t)mid; st_delete(RCLASS_M_TBL(klass), &key, &data); rb_vm_check_redefinition_opt_method(me, klass); rb_clear_cache_for_undef(klass, mid); rb_unlink_method_entry(me); CALL_METHOD_HOOK(klass, removed, mid); }
static void remove_method(VALUE klass, ID mid) { st_data_t data; NODE *body = 0; if (klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't remove method"); } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); if (mid == object_id || mid == __send__ || mid == idInitialize) { rb_warn("removing `%s' may cause serious problem", rb_id2name(mid)); } if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) { body = (NODE *)data; if (!body || !body->nd_body) body = 0; else { st_delete(RCLASS_M_TBL(klass), &mid, &data); } } if (!body) { rb_name_error(mid, "method `%s' not defined in %s", rb_id2name(mid), rb_class2name(klass)); } if (nd_type(body->nd_body->nd_body) == NODE_CFUNC) { rb_vm_check_redefinition_opt_method(body); } rb_clear_cache_for_undef(klass, mid); if (FL_TEST(klass, FL_SINGLETON)) { rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, ID2SYM(mid)); } else { rb_funcall(klass, removed, 1, ID2SYM(mid)); } }