[Bug #20302] Multiple refinements cannot be applied to the same module
In the following code, the iclass tree of refinements in cref should be <iclass of Kernel@M2> -> <iclass of Kernel@M1> -> Kernel. However, the iclass tree was broken because of code for included modules of refinements in rb_using_refinement(). Refinement#include is now removed, so this commit removes such unnecessary code. ```ruby module M1 refine(Kernel) do def f1 = :f1 end end module M2 refine(Kernel) do def f2 = :f2 end end class Foo using M1 using M2 def test p f2 #=> :f2 p f1 # expected => :f1 # actual => undefined local variable or method 'f1' for an instance of Foo end end Foo.new.test ```
This commit is contained in:
parent
3a04ea2d03
commit
d50f9ca2dd
6
eval.c
6
eval.c
@ -1276,12 +1276,6 @@ rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module)
|
||||
|
||||
RCLASS_M_TBL(c) = RCLASS_M_TBL(module);
|
||||
|
||||
module = RCLASS_SUPER(module);
|
||||
while (module && module != klass) {
|
||||
c = RCLASS_SET_SUPER(c, rb_include_class_new(module, RCLASS_SUPER(c)));
|
||||
RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
|
||||
module = RCLASS_SUPER(module);
|
||||
}
|
||||
rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
|
||||
}
|
||||
|
||||
|
@ -2672,6 +2672,35 @@ class TestRefinement < Test::Unit::TestCase
|
||||
assert_equal(:v2, obj.cached_foo_callsite)
|
||||
end
|
||||
|
||||
# [Bug #20302]
|
||||
def test_multiple_refinements_for_same_module
|
||||
assert_in_out_err([], <<-INPUT, %w(:f2 :f1), [])
|
||||
module M1
|
||||
refine(Kernel) do
|
||||
def f1 = :f1
|
||||
end
|
||||
end
|
||||
|
||||
module M2
|
||||
refine(Kernel) do
|
||||
def f2 = :f2
|
||||
end
|
||||
end
|
||||
|
||||
class Foo
|
||||
using M1
|
||||
using M2
|
||||
|
||||
def test
|
||||
p f2
|
||||
p f1
|
||||
end
|
||||
end
|
||||
|
||||
Foo.new.test
|
||||
INPUT
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def eval_using(mod, s)
|
||||
|
Loading…
x
Reference in New Issue
Block a user