ruby-changes:26271
From: shugo <ko1@a...>
Date: Wed, 12 Dec 2012 01:48:32 +0900 (JST)
Subject: [ruby-changes:26271] shugo:r38328 (trunk): * eval.c (rb_using_refinement): make the method table of an iclass
shugo 2012-12-12 01:48:21 +0900 (Wed, 12 Dec 2012) New Revision: 38328 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38328 Log: * eval.c (rb_using_refinement): make the method table of an iclass for a refinement that of the refinement, not that of the origin of the refinement, which is set by rb_include_class_new(). This change is needed to make module prepend into a refinement work properly. * test/ruby/test_refinement.rb: related test. Modified files: trunk/ChangeLog trunk/eval.c trunk/test/ruby/test_refinement.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 38327) +++ ChangeLog (revision 38328) @@ -1,3 +1,13 @@ +Wed Dec 12 01:47:02 2012 Shugo Maeda <shugo@r...> + + * eval.c (rb_using_refinement): make the method table of an iclass + for a refinement that of the refinement, not that of the origin of + the refinement, which is set by rb_include_class_new(). This + change is needed to make module prepend into a refinement work + properly. + + * test/ruby/test_refinement.rb: related test. + Wed Dec 12 01:05:04 2012 NARUSE, Yui <naruse@r...> * tool/make-snapshot: add --disable-rubygem to both MINIRUBY and RUBY. Index: eval.c =================================================================== --- eval.c (revision 38327) +++ eval.c (revision 38328) @@ -1078,6 +1078,7 @@ FL_SET(module, RMODULE_IS_OVERLAID); c = iclass = rb_include_class_new(module, superclass); RCLASS_REFINED_CLASS(c) = klass; + RCLASS_M_TBL(c) = RCLASS_M_TBL(module); module = RCLASS_SUPER(module); while (module && module != klass) { FL_SET(module, RMODULE_IS_OVERLAID); Index: test/ruby/test_refinement.rb =================================================================== --- test/ruby/test_refinement.rb (revision 38327) +++ test/ruby/test_refinement.rb (revision 38328) @@ -692,6 +692,69 @@ IncludeIntoRefinement::User.invoke_baz_on(x)) end + module PrependIntoRefinement + class C + def bar + return "C#bar" + end + + def baz + return "C#baz" + end + end + + module Mixin + def foo + return "Mixin#foo" + end + + def bar + return super << " Mixin#bar" + end + + def baz + return super << " Mixin#baz" + end + end + + module M + refine C do + prepend Mixin + + def baz + return super << " M#baz" + end + end + end + end + + eval <<-EOF, TOPLEVEL_BINDING + using TestRefinement::PrependIntoRefinement::M + + module TestRefinement::PrependIntoRefinement::User + def self.invoke_foo_on(x) + x.foo + end + + def self.invoke_bar_on(x) + x.bar + end + + def self.invoke_baz_on(x) + x.baz + end + end + EOF + + def test_prepend_into_refinement + x = PrependIntoRefinement::C.new + assert_equal("Mixin#foo", PrependIntoRefinement::User.invoke_foo_on(x)) + assert_equal("C#bar Mixin#bar", + PrependIntoRefinement::User.invoke_bar_on(x)) + assert_equal("C#baz M#baz Mixin#baz", + PrependIntoRefinement::User.invoke_baz_on(x)) + end + private def eval_using(mod, s) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/