prepend: fix mixing with include

* class.c (rb_include_module): include modules after the origin.
* class.c (include_modules_at): skip prepended modules.
* class.c (rb_prepend_module): now basic.klass in ICLASS refers the
  old original class/module.  [ruby-dev:45868][Bug #6662]
* class.c (rb_mod_ancestors): ditto.
* vm_method.c (search_method): search method entry from the origin
  iclass.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36266 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-07-02 08:06:37 +00:00
parent bd52bed97b
commit edb1fc4eb2
4 changed files with 68 additions and 55 deletions

View file

@ -1243,31 +1243,37 @@ class TestModule < Test::Unit::TestCase
def m1; [:M0] end
end
module M1
def m1; [:M1, super, :M1] end
def m1; [:M1, *super] end
end
module M2
def m1; [:M2, super, :M2] end
def m1; [:M2, *super] end
end
M3 = Module.new do
def m1; [:M3, super, :M3] end
def m1; [:M3, *super] end
end
module M4
def m1; [:M4, super, :M4] end
def m1; [:M4, *super] end
end
class C0
class C
def m1; end
end
class C0 < C
include M0
prepend M1
def m1; [:C0, super, :C0] end
def m1; [:C0, *super] end
end
class C1 < C0
prepend M2, M3
include M4
def m1; [:C1, super, :C1] end
def m1; [:C1, *super] end
end
def test_prepend
obj = C0.new
expected = [:M1,:C0,:M0]
assert_equal(expected, obj.m1)
obj = C1.new
expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2]
expected = [:M2,:M3,:C1,:M4,:M1,:C0,:M0]
assert_equal(expected, obj.m1)
end
@ -1305,13 +1311,30 @@ class TestModule < Test::Unit::TestCase
m = labeled_module("m")
c = labeled_class("c") {prepend m}
assert_equal([m, c], c.ancestors[0, 2], bug6658)
bug6662 = '[ruby-dev:45868]'
c2 = labeled_class("c2", c)
anc = c2.ancestors
assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662)
end
def test_prepend_module_ancestors
bug6659 = '[ruby-dev:45861]'
m0 = labeled_module("m0")
m1 = labeled_module("m1") {prepend m0}
m0 = labeled_module("m0") {def x; [:m0, *super] end}
m1 = labeled_module("m1") {def x; [:m1, *super] end; prepend m0}
m2 = labeled_module("m2") {def x; [:m2, *super] end; prepend m1}
c0 = labeled_class("c0") {def x; [:c0] end}
c1 = labeled_class("c1") {def x; [:c1] end; prepend m2}
c2 = labeled_class("c2", c0) {def x; [:c2, *super] end; include m2}
assert_equal([m0, m1], m1.ancestors, bug6659)
bug6662 = '[ruby-dev:45868]'
assert_equal([m0, m1, m2], m2.ancestors, bug6662)
assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662)
assert_equal([:m0, :m1, :m2, :c1], c1.new.x)
assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662)
assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x)
end
def labeled_module(name, &block)