Bug #10765 » 0001-vm_method.c-fix-remove-refined-method.patch
| test/ruby/test_refinement.rb | ||
|---|---|---|
|
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)
|
||
| vm_method.c | ||
|---|---|---|
|
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);
|
||
| ... | ... | |
|
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);
|
||
|
}
|
||
- « Previous
- 1
- 2
- 3
- Next »