aboutsummaryrefslogtreecommitdiffstats
path: root/class.c
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-10 16:05:45 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-10 16:05:45 +0000
commit7ef16d224a80a6e1e8c01b5b45ac7e2315a04e4c (patch)
treec0ac99c10c8f3d5a9e9529de1460575ae8f4d401 /class.c
parentfa7c4ab4084ac6d5ad615d133ab0dcaca2c817fb (diff)
downloadruby-7ef16d224a80a6e1e8c01b5b45ac7e2315a04e4c.tar.gz
* fix the behavior when a module is included into a refinement.
This change is a little tricky, so it might be better to prohibit module inclusion to refinements. * include/ruby/ruby.h (RMODULE_INCLUDED_INTO_REFINEMENT): new flag to represent that a module (iclass) is included into a refinement. * class.c (include_modules_at): set RMODULE_INCLUDED_INTO_REFINEMENT if klass is a refinement. * eval.c (rb_mod_refine): set the superclass of a refinement to the refined class for super. * eval.c (rb_using_refinement): skip the above superclass (the refined class) when creating iclasses for refinements. Otherwise, `using Refinement1; using Refinement2' creates iclasses: <Refinement2> -> <RefinedClass> -> <Refinement1> -> RefinedClass, where <Module> is an iclass for Module, so RefinedClass is searched before Refinement1. The correct iclasses should be <Refinement2> -> <Refinement1> -> RefinedClass. * vm_insnhelper.c (vm_search_normal_superclass): if klass is an iclass for a refinement, use the refinement's superclass instead of the iclass's superclass. Otherwise, multiple refinements are searched by super. For example, if a refinement Refinement2 includes a module M (i.e., Refinement2 -> <M> -> RefinedClass, and if refinements iclasses are <Refinement2> -> <M>' -> <Refinement1> -> RefinedClass, then super in <Refinement2> should use Refinement2's superclass <M> instead of <Refinement2>'s superclass <M>'. * vm_insnhelper.c (vm_search_super_method): do not raise a NotImplementError if current_defind_class is a module included into a refinement. Because of the change of vm_search_normal_superclass(), the receiver might not be an instance of the module('s iclass). * test/ruby/test_refinement.rb: related test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38298 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'class.c')
-rw-r--r--class.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/class.c b/class.c
index 0aa7561aa6..ca9bdef41e 100644
--- a/class.c
+++ b/class.c
@@ -720,6 +720,7 @@ include_modules_at(VALUE klass, VALUE c, VALUE module)
st_foreach(RMODULE_M_TBL(module), add_refined_method_entry_i,
(st_data_t) refined_class);
+ FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT);
}
if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
changed = 1;