[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]