summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-01 03:57:16 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-01 03:57:16 +0000
commit72d3e2b1027a1711777b83a37fd34c89b59fffff (patch)
tree0a65567dd7b8bb6d66fd1d0cb68ca40dad8c07ac /eval.c
parent551fe2bddc0de817b4aca716034f70cf53534f93 (diff)
* eval.c (rb_using_module): activate refinements in the ancestors of
the argument module to support refinement inheritance by Module#include. [ruby-core:55671] [Feature #8571] * test/ruby/test_refinement.rb: related test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41719 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/eval.c b/eval.c
index 00bddb51ac..0bf8337175 100644
--- a/eval.c
+++ b/eval.c
@@ -1118,19 +1118,43 @@ using_refinement(VALUE klass, VALUE module, VALUE arg)
return ST_CONTINUE;
}
-void
-rb_using_module(NODE *cref, VALUE module)
+static void
+using_module_recursive(NODE *cref, VALUE klass)
{
ID id_refinements;
- VALUE refinements;
+ VALUE super, module, refinements;
- Check_Type(module, T_MODULE);
+ super = RCLASS_SUPER(klass);
+ if (super) {
+ using_module_recursive(cref, super);
+ }
+ switch (BUILTIN_TYPE(klass)) {
+ case T_MODULE:
+ module = klass;
+ break;
+
+ case T_ICLASS:
+ module = RBASIC(klass)->klass;
+ break;
+
+ default:
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Module)",
+ rb_obj_classname(klass));
+ break;
+ }
CONST_ID(id_refinements, "__refinements__");
refinements = rb_attr_get(module, id_refinements);
if (NIL_P(refinements)) return;
rb_hash_foreach(refinements, using_refinement, (VALUE) cref);
}
+void
+rb_using_module(NODE *cref, VALUE module)
+{
+ Check_Type(module, T_MODULE);
+ using_module_recursive(cref, module);
+}
+
VALUE rb_refinement_module_get_refined_class(VALUE module)
{
ID id_refined_class;