Regarding your comment :
Strange, but it changes the arguments at runtime
Actually, the order of the arguments is preserved.
curry returns a new proc that efficiently collects arguments until there are enough arguments to invoke the original / proc method (based on its arity). This is achieved by returning intermediate processes:
def foo(a, b, c) { a: a, b: b, c: c } end curried_proc = foo.curry #=> #<Proc:0x007fd09b84e018 (lambda)> curried_proc[1] #=> #<Proc:0x007fd09b83e320 (lambda)> curried_proc[1][2] #=> #<Proc:0x007fd09b82cfd0 (lambda)> curried_proc[1][2][3] #=> {:a=>1, :b=>2, :c=>3}
You can pass any number of arguments at once to curries proc:
curried_proc[1][2][3] #=> {:a=>1, :b=>2, :c=>3} curried_proc[1, 2][3] #=> {:a=>1, :b=>2, :c=>3} curried_proc[1][2, 3] #=> {:a=>1, :b=>2, :c=>3} curried_proc[1, 2, 3] #=> {:a=>1, :b=>2, :c=>3}
Null arguments are ignored:
curried_proc[1][][2][][3] #=> {:a=>1, :b=>2, :c=>3}
However, you obviously cannot reorder the arguments.
An alternative to currying is a partial application that returns a new proc with lower arity, fixing one or more arguments. Unlike curry there is no built-in method for a partial application, but you can easily write your own:
my_proc = -> (arg, num) { arg * num } def fix_first(proc, arg) -> (*args) { proc[arg, *args] } end fixed_proc = fix_first(my_proc, 'foo') #=> #<Proc:0x007fa31c2070d0 (lambda)> fixed_proc[2] #=> "foofoo" fixed_proc[3] #=> "foofoofoo" [2, 3].map(&fixed_proc) #=> ["foofoo", "foofoofoo"]
Or fix the last argument:
def fix_last(proc, arg) -> (*args) { proc[*args, arg] } end fixed_proc = fix_last(my_proc, 2) #=> #<Proc:0x007fa31c2070d0 (lambda)> fixed_proc['foo']
Of course, you are not limited to fixing individual arguments. For example, you can return proc, which takes an array and converts it to an argument list:
def splat_args(proc) -> (array) { proc[*array] } end splatting_proc = splat_args(my_proc) [['foo', 1], ['bar', 2], ['baz', 3]].map(&splatting_proc)