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

ruby-changes:44140

From: shugo <ko1@a...>
Date: Fri, 23 Sep 2016 20:46:37 +0900 (JST)
Subject: [ruby-changes:44140] shugo:r56213 (trunk): * eval.c (rb_mod_refine): refine modules as well.

shugo	2016-09-23 20:46:33 +0900 (Fri, 23 Sep 2016)

  New Revision: 56213

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56213

  Log:
    * eval.c (rb_mod_refine): refine modules as well.
      [ruby-core:76199] [Feature #12534]

  Added files:
    trunk/diff
  Modified files:
    trunk/ChangeLog
    trunk/eval.c
    trunk/test/ruby/test_refinement.rb
    trunk/vm_method.c
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 56212)
+++ vm_method.c	(revision 56213)
@@ -439,13 +439,17 @@ make_method_entry_refined(VALUE owner, r https://github.com/ruby/ruby/blob/trunk/vm_method.c#L439
     }
     else {
 	struct {
-	    const struct rb_method_entry_struct *orig_me;
+	    struct rb_method_entry_struct *orig_me;
 	    VALUE owner;
 	} refined;
 
 	rb_vm_check_redefinition_opt_method(me, me->owner);
 
-	refined.orig_me = rb_method_entry_clone(me);
+	refined.orig_me =
+	    rb_method_entry_alloc(me->called_id, me->owner,
+				  me->defined_class || owner,
+				  method_definition_addref(me->def));
+	METHOD_ENTRY_FLAGS_COPY(refined.orig_me, me);
 	refined.owner = owner;
 
 	method_definition_set(me, method_definition_create(VM_METHOD_TYPE_REFINED, me->called_id), (void *)&refined);
Index: eval.c
===================================================================
--- eval.c	(revision 56212)
+++ eval.c	(revision 56213)
@@ -1092,6 +1092,16 @@ rb_mod_prepend(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/eval.c#L1092
     return module;
 }
 
+static void
+ensure_class_or_module(VALUE obj)
+{
+    if (!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE)) {
+	rb_raise(rb_eTypeError,
+		 "wrong argument type %"PRIsVALUE" (expected Class or Module)",
+		 rb_obj_class(obj));
+    }
+}
+
 static VALUE
 hidden_identity_hash_new(void)
 {
@@ -1106,7 +1116,7 @@ rb_using_refinement(rb_cref_t *cref, VAL https://github.com/ruby/ruby/blob/trunk/eval.c#L1116
 {
     VALUE iclass, c, superclass = klass;
 
-    Check_Type(klass, T_CLASS);
+    ensure_class_or_module(klass);
     Check_Type(module, T_MODULE);
     if (NIL_P(CREF_REFINEMENTS(cref))) {
 	CREF_REFINEMENTS_SET(cref, hidden_identity_hash_new());
@@ -1231,11 +1241,11 @@ add_activated_refinement(VALUE activated https://github.com/ruby/ruby/blob/trunk/eval.c#L1241
 
 /*
  *  call-seq:
- *     refine(klass) { block }   -> module
+ *     refine(mod) { block }   -> module
  *
- *  Refine <i>klass</i> in the receiver.
+ *  Refine <i>mod</i> in the receiver.
  *
- *  Returns an overlaid module.
+ *  Returns a module, where refined methods are defined.
  */
 
 static VALUE
@@ -1255,7 +1265,7 @@ rb_mod_refine(VALUE module, VALUE klass) https://github.com/ruby/ruby/blob/trunk/eval.c#L1265
 	rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");
     }
 
-    Check_Type(klass, T_CLASS);
+    ensure_class_or_module(klass);
     CONST_ID(id_refinements, "__refinements__");
     refinements = rb_attr_get(module, id_refinements);
     if (NIL_P(refinements)) {
Index: test/ruby/test_refinement.rb
===================================================================
--- test/ruby/test_refinement.rb	(revision 56212)
+++ test/ruby/test_refinement.rb	(revision 56213)
@@ -345,17 +345,64 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L345
     assert_equal([:c, :m1, :m2], x)
   end
 
-  def test_refine_module
-    m1 = Module.new
-    assert_raise(TypeError) do
-      Module.new {
-        refine m1 do
+  module RefineModule
+    module M
+      def foo
+        "M#foo"
+      end
+
+      def bar
+        "M#bar"
+      end
+
+      def baz
+        "M#baz"
+      end
+    end
+
+    class C
+      include M
+
+      def baz
+        "#{super} C#baz"
+      end
+    end
+
+    module M2
+      refine M do
         def foo
-          :m2
+          "M@M2#foo"
         end
+
+        def bar
+          "#{super} M@M2#bar"
+        end
+
+        def baz
+          "#{super} M@M2#baz"
         end
-      }
+      end
     end
+
+    using M2
+
+    def self.call_foo
+      C.new.foo
+    end
+
+    def self.call_bar
+      C.new.bar
+    end
+
+    def self.call_baz
+      C.new.baz
+    end
+  end
+
+  def test_refine_module
+    assert_equal("M@M2#foo", RefineModule.call_foo)
+    assert_equal("M#bar M@M2#bar", RefineModule.call_bar)
+    assert_equal("M#baz C#baz", RefineModule.call_baz)
   end
 
   def test_refine_neither_class_nor_module
Index: diff
===================================================================
--- diff	(revision 0)
+++ diff	(revision 56213)
@@ -0,0 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/diff#L1
+diff --git a/tool/mkconfig.rb b/tool/mkconfig.rb
+index 6b6f14c..ee0642c 100755
+--- a/tool/mkconfig.rb
++++ b/tool/mkconfig.rb
+@@ -20,7 +20,7 @@
+ require "fileutils"
+ mkconfig = File.basename($0)
+ 
+-fast = {'prefix'=>TRUE, 'ruby_install_name'=>TRUE, 'INSTALL'=>TRUE, 'EXEEXT'=>TRUE}
++fast = {'prefix'=>true, 'ruby_install_name'=>true, 'INSTALL'=>true, 'EXEEXT'=>true}
+ 
+ win32 = /mswin/ =~ arch
+ universal = /universal.*darwin/ =~ arch
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 56212)
+++ ChangeLog	(revision 56213)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Sep 23 20:36:05 2016  Shugo Maeda  <shugo@r...>
+
+	* eval.c (rb_mod_refine): refine modules as well.
+	  [ruby-core:76199] [Feature #12534]
+
 Fri Sep 23 20:19:09 2016  Akinori MUSHA  <knu@i...>
 
 	* man/ruby.1: Update the paragraphs in "Rich Libraries" which

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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