1 min read

TIL: Ruby Currying

If currying is a way to partially execute a function, here's how Ruby handles it
TIL: Ruby Currying
Photo by Raman / Unsplash

If currying is a way to partially execute a function, here's how Ruby handles it.

If I have a method which takes two arguments and I grab a reference to the method:

def say_hello(salutation, person)
  puts "#{salutation} #{person}"
end

say_hello_method = method(:say_hello)

(I do also do this with a lambda, I don't need to grab any kind of special reference.)

Now let's create a curried reference:

say_hello_curried = say_hello_method.curry

Now I can call the curry and another curried lambda back or I've supplied all the parameters I the method evaluates. Watch the assignment going on here.

say_hello_curried = say_hello_curried.call('hey')
say_hello_curried.call('Billy')
# hello Billy

Or, of course:

say_hello_curried.call('hello').call('Billy')
# hello Billy

Variable length arguments

So let's have some vargs:

def say_hello(salutation, *person)
  puts "#{salutation} #{person.join(' ')}"
end

So how do we curry that so that it eventually completes? We tell #curry how many arguments we are going to pass it.

say_hello_curried = method(:say_hello).curry(3)
say_hello_curried.call('hey').call('Billy').call('Ruffian')
# hey Billy Ruffian