ruby-changes:24994
From: shugo <ko1@a...>
Date: Fri, 28 Sep 2012 15:48:33 +0900 (JST)
Subject: [ruby-changes:24994] shugo:r37046 (trunk): * vm_method.c (search_method): copy refinement iclasses to search
shugo 2012-09-28 15:48:20 +0900 (Fri, 28 Sep 2012) New Revision: 37046 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37046 Log: * vm_method.c (search_method): copy refinement iclasses to search superclasses correctly. * test/ruby/test_refinement.rb: related test. Modified files: trunk/ChangeLog trunk/test/ruby/test_refinement.rb trunk/vm_method.c Index: ChangeLog =================================================================== --- ChangeLog (revision 37045) +++ ChangeLog (revision 37046) @@ -1,3 +1,10 @@ +Fri Sep 28 15:44:45 2012 Shugo Maeda <shugo@r...> + + * vm_method.c (search_method): copy refinement iclasses to search + superclasses correctly. + + * test/ruby/test_refinement.rb: related test. + Fri Sep 28 15:15:41 2012 Koichi Sasada <ko1@a...> * insns.def (opt_checkenv): remove unused instruction `opt_checkenv'. Index: vm_method.c =================================================================== --- vm_method.c (revision 37045) +++ vm_method.c (revision 37046) @@ -376,6 +376,24 @@ return 0; } +static VALUE +copy_refinement_iclass(VALUE iclass, VALUE superclass) +{ + VALUE result, c; + + Check_Type(iclass, T_ICLASS); + c = result = rb_include_class_new(RBASIC(iclass)->klass, superclass); + RCLASS_REFINED_CLASS(c) = RCLASS_REFINED_CLASS(iclass); + iclass = RCLASS_SUPER(iclass); + while (iclass && BUILTIN_TYPE(iclass) == T_ICLASS) { + c = RCLASS_SUPER(c) = rb_include_class_new(RBASIC(iclass)->klass, + RCLASS_SUPER(c)); + RCLASS_REFINED_CLASS(c) = RCLASS_REFINED_CLASS(iclass); + iclass = RCLASS_SUPER(iclass); + } + return result; +} + static rb_method_entry_t* search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr) { @@ -386,15 +404,12 @@ st_table *m_tbl; if (!NIL_P(omod) && klass != skipped_class) { - VALUE c; - - if (BUILTIN_TYPE(klass) == T_ICLASS) { - c = RBASIC(klass)->klass; + iclass = rb_hash_lookup(omod, klass); + if (NIL_P(iclass) && BUILTIN_TYPE(klass) == T_ICLASS) { + iclass = rb_hash_lookup(omod, RBASIC(klass)->klass); + if (!NIL_P(iclass)) + iclass = copy_refinement_iclass(iclass, klass); } - else { - c = klass; - } - iclass = rb_hash_lookup(omod, c); if (!NIL_P(iclass)) { skipped_class = klass; klass = iclass; Index: test/ruby/test_refinement.rb =================================================================== --- test/ruby/test_refinement.rb (revision 37045) +++ test/ruby/test_refinement.rb (revision 37046) @@ -361,6 +361,24 @@ assert_equal([:m1, :m2], m2.module_eval { obj.foo }) end + def test_refine_module_and_call_superclass_method + m1 = Module.new + c1 = Class.new { + def foo + "c1#foo" + end + } + c2 = Class.new(c1) { + include m1 + } + m2 = Module.new { + refine m1 do + end + } + obj = c2.new + assert_equal("c1#foo", m2.module_eval { obj.foo }) + end + def test_refine_neither_class_nor_module assert_raise(TypeError) do Module.new { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/