Project

General

Profile

Feature #9783 ยป 0001-Implement-Method-curry-which-delegates-to-to_proc.cu.patch

plexus (Arne Brasseur), 04/29/2014 07:19 AM

View differences:

proc.c
1803 1803
    return rb_method_call_with_block(argc, argv, method, proc);
1804 1804
}
1805 1805

  
1806
/*
1807
 *  call-seq:
1808
 *     meth.curry        -> proc
1809
 *     meth.curry(arity) -> proc
1810
 *
1811
 *  Returns a curried proc based on the method. When the proc is called with a number of
1812
 *  arguments that is lower than the method's arity, then another curried proc is returned.
1813
 *  Only when enough arguments have been supplied to satisfy the method signature, will the
1814
 *  method actually be called.
1815
 *
1816
 *  The optional <i>arity</i> argument should be supplied when currying methods with
1817
 *  variable arguments to determine how many arguments are needed before the method is
1818
 *  called.
1819
 *
1820
 *     def foo(a,b,c)
1821
 *       [a, b, c]
1822
 *     end
1823
 *
1824
 *     proc  = self.method(:foo).curry
1825
 *     proc2 = proc.call(1, 2)          #=> #<Proc>
1826
 *     proc2.call(3)                    #=> [1,2,3]
1827
 *
1828
 *     def vararg(*args)
1829
 *       args
1830
 *     end
1831
 *
1832
 *     proc = self.method(:vararg).curry(4)
1833
 *     proc2 = proc.call(:x)      #=> #<Proc>
1834
 *     proc3 = proc2.call(:y, :z) #=> #<Proc>
1835
 *     proc3.call(:a)             #=> [:x, :y, :z, :a]
1836
 */
1837
VALUE
1838
rb_method_curry(int argc, VALUE *argv, VALUE self)
1839
{
1840
    VALUE proc = rb_funcall(self, rb_intern("to_proc"), 0);
1841
    return rb_funcall2(proc, rb_intern("curry"), argc, argv);
1842
}
1843

  
1806 1844
VALUE
1807 1845
rb_method_call_with_block(int argc, VALUE *argv, VALUE method, VALUE pass_procval)
1808 1846
{
......
2632 2670
    rb_define_method(rb_cMethod, "hash", method_hash, 0);
2633 2671
    rb_define_method(rb_cMethod, "clone", method_clone, 0);
2634 2672
    rb_define_method(rb_cMethod, "call", rb_method_call, -1);
2673
    rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);
2635 2674
    rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
2636 2675
    rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
2637 2676
    rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
test/ruby/test_method.rb
754 754
    m = assert_nothing_raised(NameError, feature8391) {break o.singleton_method(:bar)}
755 755
    assert_equal(:bar, m.call, feature8391)
756 756
  end
757

  
758
  def test_curry
759
    c = Class.new
760
    p = proc {|a,b,c| a + b + c }
761
    c.class_eval { define_method(:three_args, p) }
762
    curried = c.new.method(:three_args).curry
763

  
764
    assert_equal(6, curried.(1).(2).(3))
765
  end
766

  
767
  def test_curry_arity
768
    c = Class.new
769
    p = proc {|*args| args }
770
    c.class_eval { define_method(:var_args, p) }
771
    curried = c.new.method(:var_args).curry(3)
772

  
773
    assert_equal([1, 2, 3], curried.(1).(2).(3))
774
  end
757 775
end
758
-