* class.c (rb_include_module): revert duplicate inclusion of
modules. [ruby-dev:29793] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11291 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
568602aeea
commit
6f1c934bc3
@ -1,3 +1,8 @@
|
|||||||
|
Tue Nov 7 17:52:08 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* class.c (rb_include_module): revert duplicate inclusion of
|
||||||
|
modules. [ruby-dev:29793]
|
||||||
|
|
||||||
Tue Nov 7 17:18:11 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Tue Nov 7 17:18:11 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* eval.c (method_missing): update old argument adjustment.
|
* eval.c (method_missing): update old argument adjustment.
|
||||||
|
24
class.c
24
class.c
@ -344,7 +344,7 @@ include_class_new(VALUE module, VALUE super)
|
|||||||
void
|
void
|
||||||
rb_include_module(VALUE klass, VALUE module)
|
rb_include_module(VALUE klass, VALUE module)
|
||||||
{
|
{
|
||||||
VALUE c;
|
VALUE p, c;
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
|
|
||||||
rb_frozen_class_p(klass);
|
rb_frozen_class_p(klass);
|
||||||
@ -359,11 +359,29 @@ rb_include_module(VALUE klass, VALUE module)
|
|||||||
OBJ_INFECT(klass, module);
|
OBJ_INFECT(klass, module);
|
||||||
c = klass;
|
c = klass;
|
||||||
while (module) {
|
while (module) {
|
||||||
|
int superclass_seen = Qfalse;
|
||||||
|
|
||||||
if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
|
if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
|
||||||
rb_raise(rb_eArgError, "cyclic include detected");
|
rb_raise(rb_eArgError, "cyclic include detected");
|
||||||
RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
|
/* ignore if the module included already in superclasses */
|
||||||
c = RCLASS(c)->super;
|
for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
|
||||||
|
switch (BUILTIN_TYPE(p)) {
|
||||||
|
case T_ICLASS:
|
||||||
|
if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
|
||||||
|
if (!superclass_seen) {
|
||||||
|
c = p; /* move insertion point */
|
||||||
|
}
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case T_CLASS:
|
||||||
|
superclass_seen = Qtrue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
|
||||||
changed = 1;
|
changed = 1;
|
||||||
|
skip:
|
||||||
module = RCLASS(module)->super;
|
module = RCLASS(module)->super;
|
||||||
}
|
}
|
||||||
if (changed) rb_clear_cache();
|
if (changed) rb_clear_cache();
|
||||||
|
@ -1939,7 +1939,7 @@ module M003; include M002; end
|
|||||||
module M002; include M001; end
|
module M002; include M001; end
|
||||||
module M003; include M002; end
|
module M003; include M002; end
|
||||||
|
|
||||||
test_ok(M003.ancestors == [M003, M002, M001, M002])
|
test_ok(M003.ancestors == [M003, M002, M001])
|
||||||
|
|
||||||
test_check "marshal"
|
test_check "marshal"
|
||||||
$x = [1,2,3,[4,5,"foo"],{1=>"bar"},2.5,fact(30)]
|
$x = [1,2,3,[4,5,"foo"],{1=>"bar"},2.5,fact(30)]
|
||||||
|
@ -23,6 +23,6 @@ class TestClone < Test::Unit::TestCase
|
|||||||
|
|
||||||
assert_raises(NoMethodError) {foo.test2}
|
assert_raises(NoMethodError) {foo.test2}
|
||||||
|
|
||||||
assert_equal([M003, M002, M001, M002], M003.ancestors)
|
assert_equal([M003, M002, M001], M003.ancestors)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user