summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-03-17 16:12:28 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-03-17 16:12:28 +0000
commitc4b21f736ebb339fc46760f800851a7eed444c47 (patch)
tree9b91a296b71a5a44a0e9bbb57dda46af94845140 /vm_method.c
parent5d3b8d0d5491096a10ae332db759b01c89a10f9d (diff)
merge revision(s) r49222,r49480,r49493: [Backport #10765]
method.h: UNDEFINED_REFINED_METHOD_P * method.h (UNDEFINED_REFINED_METHOD_P): macro to tell if refined original method is defined. * vm_method.c (remove_method): When remove refined method, raise a NameError if the method is not defined in refined class. But if the method is defined in refined class, it should keep refined method and remove original method. Patch by Seiei Higa. [ruby-core:67722] [Bug #10765] * class.c (method_entry_i, class_instance_method_list, rb_obj_singleton_methods): should not include methods of superclasses if recur is false. [ruby-dev:48854] [Bug #10826] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@49992 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/vm_method.c b/vm_method.c
index c084d52e84..84b4e86734 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -732,10 +732,12 @@ remove_method(VALUE klass, ID 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)) {
+ (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF) ||
+ UNDEFINED_REFINED_METHOD_P(me->def)) {
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);
@@ -743,6 +745,10 @@ remove_method(VALUE klass, ID mid)
rb_clear_method_cache_by_class(klass);
rb_unlink_method_entry(me);
+ if (me->def->type == VM_METHOD_TYPE_REFINED) {
+ rb_add_refined_method_entry(klass, mid);
+ }
+
CALL_METHOD_HOOK(self, removed, mid);
}
@@ -812,8 +818,7 @@ rb_export_method(VALUE klass, ID name, rb_method_flag_t noex)
}
if (UNDEFINED_METHOD_ENTRY_P(me) ||
- (me->def->type == VM_METHOD_TYPE_REFINED &&
- UNDEFINED_METHOD_ENTRY_P(me->def->body.orig_me))) {
+ UNDEFINED_REFINED_METHOD_P(me->def)) {
rb_print_undef(klass, name, 0);
}
@@ -912,8 +917,7 @@ rb_undef(VALUE klass, ID id)
me = search_method(klass, id, 0);
if (UNDEFINED_METHOD_ENTRY_P(me) ||
- (me->def->type == VM_METHOD_TYPE_REFINED &&
- UNDEFINED_METHOD_ENTRY_P(me->def->body.orig_me))) {
+ UNDEFINED_REFINED_METHOD_P(me->def)) {
const char *s0 = " class";
VALUE c = klass;
@@ -1260,8 +1264,7 @@ rb_alias(VALUE klass, ID name, ID def)
orig_me = search_method(klass, def, &defined_class);
if (UNDEFINED_METHOD_ENTRY_P(orig_me) ||
- (orig_me->def->type == VM_METHOD_TYPE_REFINED &&
- UNDEFINED_METHOD_ENTRY_P(orig_me->def->body.orig_me))) {
+ UNDEFINED_REFINED_METHOD_P(orig_me->def)) {
if ((!RB_TYPE_P(klass, T_MODULE)) ||
(orig_me = search_method(rb_cObject, def, 0),
UNDEFINED_METHOD_ENTRY_P(orig_me))) {