1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Make Module#prepend affect the iclasses of the module

3556a834a2 added support for
Module#include to affect the iclasses of the module.  It didn't add
support for Module#prepend because there were bugs in the object model
and GC at the time that prevented it.  Those problems have been
addressed in ad729a1d11 and
98286e9850, and now adding support for
it is straightforward and does not break any tests or specs.

Fixes [Bug #9573]
This commit is contained in:
Jeremy Evans 2020-06-03 12:14:49 -07:00
parent 750203c514
commit 41582d5866
Notes: git 2020-06-19 00:19:04 +09:00
2 changed files with 29 additions and 0 deletions

View file

@ -1141,6 +1141,13 @@ rb_prepend_module(VALUE klass, VALUE module)
if (changed) {
rb_vm_check_redefinition_by_prepend(klass);
}
if (RB_TYPE_P(klass, T_MODULE)) {
rb_subclass_entry_t *iclass = RCLASS_EXT(klass)->subclasses;
while (iclass) {
include_modules_at(iclass->klass, iclass->klass, module, FALSE);
iclass = iclass->next;
}
}
}
/*

View file

@ -587,6 +587,28 @@ class TestModule < Test::Unit::TestCase
m1.include m2
m1.include m3
assert_equal([:m1, :sc, :m2, :m3, :c], o.foo)
m1, m2, m3, sc, o = modules.call
assert_equal([:sc, :c], o.foo)
sc.prepend m1
assert_equal([:m1, :sc, :c], o.foo)
m1.prepend m2
assert_equal([:m2, :m1, :sc, :c], o.foo)
m2.prepend m3
assert_equal([:m3, :m2, :m1, :sc, :c], o.foo)
m1, m2, m3, sc, o = modules.call
sc.include m1
assert_equal([:sc, :m1, :c], o.foo)
sc.prepend m2
assert_equal([:m2, :sc, :m1, :c], o.foo)
sc.prepend m3
assert_equal([:m3, :m2, :sc, :m1, :c], o.foo)
m1, m2, m3, sc, o = modules.call
sc.include m1
assert_equal([:sc, :m1, :c], o.foo)
m2.prepend m3
m1.include m2
assert_equal([:sc, :m1, :m3, :m2, :c], o.foo)
end
def test_included_modules