From 72d3e2b1027a1711777b83a37fd34c89b59fffff Mon Sep 17 00:00:00 2001 From: shugo Date: Mon, 1 Jul 2013 03:57:16 +0000 Subject: * 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 --- eval.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'eval.c') 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; -- cgit v1.2.3