summaryrefslogtreecommitdiff
path: root/class.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-27 12:31:17 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-27 12:31:17 +0000
commitcf3a8f09b806dc6f31363e845d9e93d5e046af91 (patch)
treeee53fb2bf706675f383362bd386f6eeab1ae42f3 /class.c
parent48c04ad0d82ec4339ffd12ad4717b4dbde2aa74f (diff)
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.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/class.c b/class.c
index 099f016d97..537401582a 100644
--- a/class.c
+++ b/class.c
@@ -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();
}
/*