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

ruby-changes:53696

From: nobu <ko1@a...>
Date: Thu, 22 Nov 2018 14:51:46 +0900 (JST)
Subject: [ruby-changes:53696] nobu:r65912 (trunk): proc.c: Implement Method#* for Method composition

nobu	2018-11-22 14:51:41 +0900 (Thu, 22 Nov 2018)

  New Revision: 65912

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

  Log:
    proc.c: Implement Method#* for Method composition
    
    * proc.c (rb_method_compose): Implement Method#* for Method composition,
      which delegates to Proc#*.
    
    * test/ruby/test_method.rb: Add test cases for Method composition.
    
    From: Paul Mucur <mudge@m...>

  Modified files:
    trunk/proc.c
    trunk/test/ruby/test_method.rb
Index: test/ruby/test_method.rb
===================================================================
--- test/ruby/test_method.rb	(revision 65911)
+++ test/ruby/test_method.rb	(revision 65912)
@@ -1040,4 +1040,38 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L1040
     assert_operator(0.method(:<), :===, 5)
     assert_not_operator(0.method(:<), :===, -5)
   end
+
+  def test_compose_with_method
+    c = Class.new {
+      def f(x) x * 2 end
+      def g(x) x + 1 end
+    }
+    f = c.new.method(:f)
+    g = c.new.method(:g)
+    h = f * g
+
+    assert_equal(6, h.call(2))
+  end
+
+  def test_compose_with_proc
+    c = Class.new {
+      def f(x) x * 2 end
+    }
+    f = c.new.method(:f)
+    g = proc {|x| x + 1}
+    h = f * g
+
+    assert_equal(6, h.call(2))
+  end
+
+  def test_compose_with_nonproc_or_method
+    c = Class.new {
+      def f(x) x * 2 end
+    }
+    f = c.new.method(:f)
+
+    assert_raise(TypeError) {
+      f * 5
+    }
+  end
 end
Index: proc.c
===================================================================
--- proc.c	(revision 65911)
+++ proc.c	(revision 65912)
@@ -3100,6 +3100,30 @@ proc_compose(VALUE self, VALUE g) https://github.com/ruby/ruby/blob/trunk/proc.c#L3100
 }
 
 /*
+ *  call-seq:
+ *     meth * g -> a_proc
+ *
+ *  Returns a proc that is the composition of this method and the given proc <i>g</i>.
+ *  The returned proc takes a variable number of arguments, calls <i>g</i> with them
+ *  then calls this method with the result.
+ *
+ *     def f(x)
+ *       x * 2
+ *     end
+ *
+ *     f = self.method(:f)
+ *     g = proc {|x, y| x + y }
+ *     h = f * g
+ *     p h.call(1, 2) #=> 6
+ */
+static VALUE
+rb_method_compose(VALUE self, VALUE g)
+{
+    VALUE proc = method_to_proc(self);
+    return proc_compose(proc, g);
+}
+
+/*
  *  Document-class: LocalJumpError
  *
  *  Raised when Ruby can't yield as requested.
@@ -3222,6 +3246,7 @@ Init_Proc(void) https://github.com/ruby/ruby/blob/trunk/proc.c#L3246
     rb_define_method(rb_cMethod, "call", rb_method_call, -1);
     rb_define_method(rb_cMethod, "===", rb_method_call, -1);
     rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);
+    rb_define_method(rb_cMethod, "*", rb_method_compose, 1);
     rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
     rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
     rb_define_method(rb_cMethod, "inspect", method_inspect, 0);

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

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