зеркало из https://github.com/github/ruby.git
Avoid setting the visibility of refinement method entries
Since refinement search is always performed, these entries should always be public. The method entry that the refinement search returns decides the visibility. Fixes [Bug #17822]
This commit is contained in:
Родитель
50a534a152
Коммит
636d4f7eb9
|
@ -2537,6 +2537,28 @@ class TestRefinement < Test::Unit::TestCase
|
|||
assert_equal(:second, klass.new.foo)
|
||||
end
|
||||
|
||||
class Bug17822
|
||||
module Ext
|
||||
refine(Bug17822) do
|
||||
def foo = :refined
|
||||
end
|
||||
end
|
||||
|
||||
private(def foo = :not_refined)
|
||||
|
||||
module Client
|
||||
using Ext
|
||||
def self.call_foo
|
||||
Bug17822.new.foo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# [Bug #17822]
|
||||
def test_privatizing_refined_method
|
||||
assert_equal(:refined, Bug17822::Client.call_foo)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def eval_using(mod, s)
|
||||
|
|
15
vm_method.c
15
vm_method.c
|
@ -1409,11 +1409,16 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
|
|||
rb_vm_check_redefinition_opt_method(me, klass);
|
||||
|
||||
if (klass == defined_class || origin_class == defined_class) {
|
||||
METHOD_ENTRY_VISI_SET(me, visi);
|
||||
|
||||
if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
|
||||
METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
|
||||
}
|
||||
if (me->def->type == VM_METHOD_TYPE_REFINED) {
|
||||
// Refinement method entries should always be public because the refinement
|
||||
// search is always performed.
|
||||
if (me->def->body.refined.orig_me) {
|
||||
METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
|
||||
}
|
||||
}
|
||||
else {
|
||||
METHOD_ENTRY_VISI_SET(me, visi);
|
||||
}
|
||||
rb_clear_method_cache(klass, name);
|
||||
}
|
||||
else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче