ruby-changes:24186
From: nobu <ko1@a...>
Date: Wed, 27 Jun 2012 21:32:25 +0900 (JST)
Subject: [ruby-changes:24186] nobu:r36237 (trunk): ancestor modules
nobu 2012-06-27 21:31:17 +0900 (Wed, 27 Jun 2012) New Revision: 36237 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36237 Log: ancestor modules * class.c (rb_prepend_module): ancestors of prepending module also should be included. [ruby-core:45914][Bug #6654] Modified files: trunk/ChangeLog trunk/class.c trunk/test/ruby/test_module.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 36236) +++ ChangeLog (revision 36237) @@ -1,3 +1,8 @@ +Wed Jun 27 21:31:13 2012 Nobuyoshi Nakada <nobu@r...> + + * class.c (rb_prepend_module): ancestors of prepending module also + should be included. [ruby-core:45914][Bug #6654] + Wed Jun 27 21:01:32 2012 Nobuyoshi Nakada <nobu@r...> * class.c (class_instance_method_list): m_tbl in prepended Index: class.c =================================================================== --- class.c (revision 36236) +++ class.c (revision 36237) @@ -650,10 +650,11 @@ return (VALUE)klass; } +static int include_modules_at(VALUE klass, VALUE c, VALUE module); + void rb_include_module(VALUE klass, VALUE module) { - VALUE p, c; int changed = 0; rb_frozen_class_p(klass); @@ -666,7 +667,17 @@ } OBJ_INFECT(klass, module); - c = klass; + + changed = include_modules_at(klass, klass, module); + if (changed) rb_clear_cache(); +} + +static int +include_modules_at(VALUE klass, VALUE c, VALUE module) +{ + VALUE p; + int changed = 0; + while (module) { int superclass_seen = FALSE; @@ -696,13 +707,15 @@ skip: module = RCLASS_SUPER(module); } - if (changed) rb_clear_cache(); + + return changed; } void rb_prepend_module(VALUE klass, VALUE module) { VALUE p, c, origin; + int changed = 0; rb_frozen_class_p(klass); if (!OBJ_UNTRUSTED(klass)) { @@ -714,7 +727,7 @@ OBJ_INFECT(klass, module); c = RCLASS_SUPER(klass); if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module)) - rb_raise(rb_eArgError, "cyclic include detected"); + rb_raise(rb_eArgError, "cyclic prepend detected"); for (p = c; p; p = RCLASS_SUPER(p)) { if (BUILTIN_TYPE(p) == T_ICLASS) { if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) { @@ -733,9 +746,12 @@ c = origin; } RCLASS_SUPER(klass) = include_class_new(module, c); - if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries) { - rb_clear_cache_by_class(klass); + if (RCLASS_SUPER(module)) { + changed = include_modules_at(klass, RCLASS_SUPER(klass), RCLASS_SUPER(module)); } + if (!changed) + changed = RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries; + if (changed) rb_clear_cache(); } /* Index: test/ruby/test_module.rb =================================================================== --- test/ruby/test_module.rb (revision 36236) +++ test/ruby/test_module.rb (revision 36237) @@ -1271,6 +1271,15 @@ assert_equal(expected, obj.m1) end + def test_prepend_inheritance + bug6654 = '[ruby-core:45914]' + a = Module.new + b = Module.new {include a} + c = Class.new {prepend b} + assert_operator(c, :<, b, bug6654) + assert_operator(c, :<, a, bug6654) + end + def test_prepend_instance_methods bug6655 = '[ruby-core:45915]' assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/