diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-06-27 12:31:17 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-06-27 12:31:17 +0000 |
commit | cf3a8f09b806dc6f31363e845d9e93d5e046af91 (patch) | |
tree | ee53fb2bf706675f383362bd386f6eeab1ae42f3 /class.c | |
parent | 48c04ad0d82ec4339ffd12ad4717b4dbde2aa74f (diff) | |
download | ruby-cf3a8f09b806dc6f31363e845d9e93d5e046af91.tar.gz |
ancestor modules
* class.c (rb_prepend_module): ancestors of prepending module also
should be included. [ruby-core:45914][Bug #6654]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36237 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'class.c')
-rw-r--r-- | class.c | 28 |
1 files changed, 22 insertions, 6 deletions
@@ -650,10 +650,11 @@ include_class_new(VALUE module, VALUE super) 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 @@ rb_include_module(VALUE klass, VALUE module) } 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 @@ rb_include_module(VALUE klass, VALUE module) 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 @@ rb_prepend_module(VALUE klass, VALUE module) 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 @@ rb_prepend_module(VALUE klass, VALUE module) 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(); } /* |