зеркало из https://github.com/github/ruby.git
proc.c: Implement Method#curry
* proc.c (rb_method_curry): Implement Method#curry, which delegates to to_proc.curry. [ruby-core:62212] [Feature #9783] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46461 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
2443fbcccf
Коммит
b2066b11d8
|
@ -1,3 +1,8 @@
|
|||
Thu Jun 19 13:39:11 2014 Arne Brasseur <arne@arnebrasseur.net>
|
||||
|
||||
* proc.c (rb_method_curry): Implement Method#curry, which delegates
|
||||
to to_proc.curry. [ruby-core:62212] [Feature #9783]
|
||||
|
||||
Tue Jun 17 16:41:49 2014 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* lib/net/ftp.rb (gets, readline): read lines without LF properly.
|
||||
|
|
4
NEWS
4
NEWS
|
@ -55,6 +55,10 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Matrix#cofactor(row, column) returns the (row, column) cofactor
|
||||
which is obtained by multiplying the first minor by (-1)**(row + column).
|
||||
|
||||
* Method
|
||||
* New methods:
|
||||
* Method#curry([arity]) returns a curried Proc.
|
||||
|
||||
=== Core classes compatibility issues (excluding feature bug fixes)
|
||||
|
||||
* IO
|
||||
|
|
42
proc.c
42
proc.c
|
@ -2584,7 +2584,7 @@ curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc)
|
|||
* p b.curry[] #=> :foo
|
||||
*/
|
||||
static VALUE
|
||||
proc_curry(int argc, VALUE *argv, VALUE self)
|
||||
proc_curry(int argc, const VALUE *argv, VALUE self)
|
||||
{
|
||||
int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);
|
||||
VALUE arity;
|
||||
|
@ -2603,6 +2603,45 @@ proc_curry(int argc, VALUE *argv, VALUE self)
|
|||
return make_curry_proc(self, rb_ary_new(), arity);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* meth.curry -> proc
|
||||
* meth.curry(arity) -> proc
|
||||
*
|
||||
* Returns a curried proc based on the method. When the proc is called with a number of
|
||||
* arguments that is lower than the method's arity, then another curried proc is returned.
|
||||
* Only when enough arguments have been supplied to satisfy the method signature, will the
|
||||
* method actually be called.
|
||||
*
|
||||
* The optional <i>arity</i> argument should be supplied when currying methods with
|
||||
* variable arguments to determine how many arguments are needed before the method is
|
||||
* called.
|
||||
*
|
||||
* def foo(a,b,c)
|
||||
* [a, b, c]
|
||||
* end
|
||||
*
|
||||
* proc = self.method(:foo).curry
|
||||
* proc2 = proc.call(1, 2) #=> #<Proc>
|
||||
* proc2.call(3) #=> [1,2,3]
|
||||
*
|
||||
* def vararg(*args)
|
||||
* args
|
||||
* end
|
||||
*
|
||||
* proc = self.method(:vararg).curry(4)
|
||||
* proc2 = proc.call(:x) #=> #<Proc>
|
||||
* proc3 = proc2.call(:y, :z) #=> #<Proc>
|
||||
* proc3.call(:a) #=> [:x, :y, :z, :a]
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
rb_method_curry(int argc, const VALUE *argv, VALUE self)
|
||||
{
|
||||
VALUE proc = method_proc(self);
|
||||
return proc_curry(argc, argv, proc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-class: LocalJumpError
|
||||
*
|
||||
|
@ -2723,6 +2762,7 @@ Init_Proc(void)
|
|||
rb_define_method(rb_cMethod, "hash", method_hash, 0);
|
||||
rb_define_method(rb_cMethod, "clone", method_clone, 0);
|
||||
rb_define_method(rb_cMethod, "call", rb_method_call, -1);
|
||||
rb_define_method(rb_cMethod, "curry", rb_method_curry, -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);
|
||||
|
|
|
@ -755,4 +755,55 @@ class TestMethod < Test::Unit::TestCase
|
|||
m = assert_nothing_raised(NameError, feature8391) {break o.singleton_method(:bar)}
|
||||
assert_equal(:bar, m.call, feature8391)
|
||||
end
|
||||
|
||||
Feature9783 = '[ruby-core:62212] [Feature #9783]'
|
||||
|
||||
def assert_curry_three_args(m)
|
||||
curried = m.curry
|
||||
assert_equal(6, curried.(1).(2).(3), Feature9783)
|
||||
|
||||
curried = m.curry(3)
|
||||
assert_equal(6, curried.(1).(2).(3), Feature9783)
|
||||
|
||||
assert_raise_with_message(ArgumentError, /wrong number/) {m.curry(2)}
|
||||
end
|
||||
|
||||
def test_curry_method
|
||||
c = Class.new {
|
||||
def three_args(a,b,c) a + b + c end
|
||||
}
|
||||
assert_curry_three_args(c.new.method(:three_args))
|
||||
end
|
||||
|
||||
def test_curry_from_proc
|
||||
c = Class.new {
|
||||
define_method(:three_args) {|a,b,c| a + b + c}
|
||||
}
|
||||
assert_curry_three_args(c.new.method(:three_args))
|
||||
end
|
||||
|
||||
def assert_curry_var_args(m)
|
||||
curried = m.curry(3)
|
||||
assert_equal([1, 2, 3], curried.(1).(2).(3), Feature9783)
|
||||
|
||||
curried = m.curry(2)
|
||||
assert_equal([1, 2], curried.(1).(2), Feature9783)
|
||||
|
||||
curried = m.curry(0)
|
||||
assert_equal([1], curried.(1), Feature9783)
|
||||
end
|
||||
|
||||
def test_curry_var_args
|
||||
c = Class.new {
|
||||
def var_args(*args) args end
|
||||
}
|
||||
assert_curry_var_args(c.new.method(:var_args))
|
||||
end
|
||||
|
||||
def test_curry_from_proc_var_args
|
||||
c = Class.new {
|
||||
define_method(:var_args) {|*args| args}
|
||||
}
|
||||
assert_curry_var_args(c.new.method(:var_args))
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче