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

ruby-changes:53697

From: nobu <ko1@a...>
Date: Thu, 22 Nov 2018 14:51:48 +0900 (JST)
Subject: [ruby-changes:53697] nobu:r65913 (trunk): proc.c: Support any callable when composing Procs

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

  New Revision: 65913

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

  Log:
    proc.c: Support any callable when composing Procs
    
    * proc.c (proc_compose): support any object with a call method rather
      than supporting only procs. [Feature #6284]
    
    * proc.c (compose): use the function call on the given object rather
      than rb_proc_call_with_block in order to support any object.
    
    * test/ruby/test_proc.rb: Add test cases for composing Procs with
      callable objects.
    
    * test/ruby/test_method.rb: Add test cases for composing Methods with
      callable objects.
    
    From: Paul Mucur <paul@a...>

  Modified files:
    trunk/proc.c
    trunk/test/ruby/test_method.rb
    trunk/test/ruby/test_proc.rb
Index: proc.c
===================================================================
--- proc.c	(revision 65912)
+++ proc.c	(revision 65913)
@@ -3052,7 +3052,7 @@ compose(VALUE dummy, VALUE args, int arg https://github.com/ruby/ruby/blob/trunk/proc.c#L3052
     VALUE f, g, fargs;
     f = RARRAY_AREF(args, 0);
     g = RARRAY_AREF(args, 1);
-    fargs = rb_ary_new3(1, rb_proc_call_with_block(g, argc, argv, passed_proc));
+    fargs = rb_ary_new3(1, rb_funcall_with_block(g, idCall, argc, argv, passed_proc));
 
     return rb_proc_call(f, fargs);
 }
@@ -3061,7 +3061,7 @@ compose(VALUE dummy, VALUE args, int arg https://github.com/ruby/ruby/blob/trunk/proc.c#L3061
  *  call-seq:
  *     prc * g -> a_proc
  *
- *  Returns a proc that is the composition of this proc and the given proc <i>g</i>.
+ *  Returns a proc that is the composition of this proc and the given <i>g</i>.
  *  The returned proc takes a variable number of arguments, calls <i>g</i> with them
  *  then calls this proc with the result.
  *
@@ -3077,16 +3077,6 @@ proc_compose(VALUE self, VALUE g) https://github.com/ruby/ruby/blob/trunk/proc.c#L3077
     rb_proc_t *procp;
     int is_lambda;
 
-    if (!rb_obj_is_method(g) && !rb_obj_is_proc(g)) {
-        rb_raise(rb_eTypeError,
-                "wrong argument type %s (expected Proc/Method)",
-                rb_obj_classname(g));
-    }
-
-    if (rb_obj_is_method(g)) {
-        g = method_to_proc(g);
-    }
-
     args = rb_ary_new3(2, self, g);
 
     GetProcPtr(self, procp);
@@ -3103,7 +3093,7 @@ proc_compose(VALUE self, VALUE g) https://github.com/ruby/ruby/blob/trunk/proc.c#L3093
  *  call-seq:
  *     meth * g -> a_proc
  *
- *  Returns a proc that is the composition of this method and the given proc <i>g</i>.
+ *  Returns a proc that is the composition of this method and the given <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.
  *
Index: test/ruby/test_proc.rb
===================================================================
--- test/ruby/test_proc.rb	(revision 65912)
+++ test/ruby/test_proc.rb	(revision 65913)
@@ -1460,11 +1460,22 @@ class TestProc < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_proc.rb#L1460
     assert_equal(6, h.call(2))
   end
 
-  def test_compose_with_nonproc_or_method
+  def test_compose_with_callable
     f = proc {|x| x * 2}
+    c = Class.new {
+      def call(x) x + 1 end
+    }
+    g = f * c.new
+
+    assert_equal(6, g.call(2))
+  end
+
+  def test_compose_with_noncallable
+    f = proc {|x| x * 2}
+    g = f * 5
 
-    assert_raise(TypeError) {
-      f * 5
+    assert_raise(NoMethodError) {
+      g.call(2)
     }
   end
 end
Index: test/ruby/test_method.rb
===================================================================
--- test/ruby/test_method.rb	(revision 65912)
+++ test/ruby/test_method.rb	(revision 65913)
@@ -1064,14 +1064,28 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L1064
     assert_equal(6, h.call(2))
   end
 
-  def test_compose_with_nonproc_or_method
+  def test_compose_with_callable
+    c = Class.new {
+      def f(x) x * 2 end
+    }
+    c2 = Class.new {
+      def call(x) x + 1 end
+    }
+    f = c.new.method(:f)
+    g = f * c2.new
+
+    assert_equal(6, g.call(2))
+  end
+
+  def test_compose_with_noncallable
     c = Class.new {
       def f(x) x * 2 end
     }
     f = c.new.method(:f)
+    g = f * 5
 
-    assert_raise(TypeError) {
-      f * 5
+    assert_raise(NoMethodError) {
+      g.call(2)
     }
   end
 end

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

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