mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49480 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
338bd4cc65
commit
525f515f9a
3 changed files with 71 additions and 1 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
Tue Feb 3 15:23:58 2015 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* 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]
|
||||
|
||||
Tue Feb 3 14:04:47 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* dir.c (glob_helper): obtain real name with FindFirstFile API
|
||||
|
|
|
@ -1310,6 +1310,58 @@ class TestRefinement < Test::Unit::TestCase
|
|||
end;
|
||||
end
|
||||
|
||||
def test_remove_refined_method
|
||||
assert_separately([], <<-"end;")
|
||||
bug10765 = '[ruby-core:67722] [Bug #10765]'
|
||||
|
||||
class C
|
||||
def foo
|
||||
"C#foo"
|
||||
end
|
||||
end
|
||||
|
||||
module RefinementBug
|
||||
refine C do
|
||||
def foo
|
||||
"RefinementBug#foo"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
using RefinementBug
|
||||
|
||||
class C
|
||||
remove_method :foo
|
||||
end
|
||||
|
||||
assert_equal("RefinementBug#foo", C.new.foo, bug10765)
|
||||
end;
|
||||
end
|
||||
|
||||
def test_remove_undefined_refined_method
|
||||
assert_separately([], <<-"end;")
|
||||
bug10765 = '[ruby-core:67722] [Bug #10765]'
|
||||
|
||||
class C
|
||||
end
|
||||
|
||||
module RefinementBug
|
||||
refine C do
|
||||
def foo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
using RefinementBug
|
||||
|
||||
assert_raise(NameError, bug10765) {
|
||||
class C
|
||||
remove_method :foo
|
||||
end
|
||||
}
|
||||
end;
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def eval_using(mod, s)
|
||||
|
|
|
@ -766,10 +766,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 `%"PRIsVALUE"' not defined in %"PRIsVALUE,
|
||||
rb_id2str(mid), rb_class_path(klass));
|
||||
}
|
||||
|
||||
key = (st_data_t)mid;
|
||||
st_delete(RCLASS_M_TBL(klass), &key, &data);
|
||||
|
||||
|
@ -777,6 +779,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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue