Skip to content

Instantly share code, notes, and snippets.

@beezee
Created December 15, 2015 14:49
Show Gist options
  • Save beezee/cb60b16a9b04d30123fc to your computer and use it in GitHub Desktop.
Save beezee/cb60b16a9b04d30123fc to your computer and use it in GitHub Desktop.
Proc#real_arity
# Currying a proc causes #arity to return -1
#
# This adds a #real_arity method to a Proc that always reflects the
# number of *remaining* parameters to be accepted (minus any partially applied)
class Proc
@r_arity = nil
def real_arity
@r_arity || arity
end
o_curry = instance_method(:curry)
define_method(:curry) do |*i|
ar = real_arity
o_curry.bind(self).(*i).tap do |o|
o.instance_eval { @r_arity = i.first || ar }
end
end
o_call = instance_method(:call)
define_method(:call) do |*args|
ar = real_arity
o_call.bind(self).(*args).tap do |r|
n_ar = ar - args.size
r.instance_eval { @r_arity = n_ar } if r.kind_of?(Proc)
end
end
end
add = ->(a, b) { a + b }.curry
add.arity # => -1
add.real_arity # => 2
add1 = add.(1)
add1.arity # => -1
add1.real_arity # => 1
@beezee
Copy link
Author

beezee commented Dec 15, 2015

Ruby procs return -1 as arity for any curried Proc. Knowing the arity of a curried proc turns out to be pretty useful if you are working with a number of them in various stages of partial application.

This monkey patches a #real_arity method on that always returns the correct value

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment