Ruby blocks made easy, part II, curry and procs as arguments

In the previous post, we learned that methods can be transformed into procs to be evaluated later.

One thing worth to mention is that, the method itself can be used like a proc: every Method structure has a method called call:

Time.now # => 2021…


This content originally appeared on DEV Community and was authored by Leandro Proença

In the previous post, we learned that methods can be transformed into procs to be evaluated later.

One thing worth to mention is that, the method itself can be used like a proc: every Method structure has a method called call:

Time.now # => 2021-04-10 17:22:05

Time.method(:now).call # => 2021-04-10 17:22:06
Time.method(:now).to_proc.call # => 2021-04-10 17:22:07

# checking the classes
Time.method(:now).class # => Method
Time.method(:now).to_proc.class # => Proc (lambda)

Given that, the method structure is good enough to be used in later evaluations. In theory, it is NOT a Proc. But in practice, it behaves like proc lambdas and will evaluate the expression later.

We can also evaluate methods later with arguments:

def multiply(a, b)
  a + b
end

method(:multiply).call(2, 4) # => 8

Proc with arguments (curry)

Sometimes it's useful to define a proc with some static arguments, which can be evaluated later along with the dynamic arguments. These arguments can be "curried" to the proc using the method .curry:

# creates a proc with no curried arguments
#   and calls using two dynamic arguments
method(:multiply).call(2, 4) # => 8

# creates a proc with the first argument curried
#   and calls using one remaining dynamic argument
method(:multiply).curry[2].call(4) # => 8
method(:multiply).curry[3].call(5) # => 15

# checking the class
method(:multiply).class # => Proc
method(:multiply).curry[4].class # => It's also a Proc

This feature is powerful because it allows us to write more expressive code:

multiply_by_2 = method(:multiply).curry[2]
multiply_by_3 = method(:multiply).curry[3]

multiply_by_2.call(4) # => 8
multiply_by_3.call(6) # => 18

Passing a lambda method as argument to another method

Lambda methods can be passed as arguments to methods like any other valid expression.

Let's suppose we want a method which takes a list of numbers and applies some calculation method to each number, returning a new calculated list:

def map_numbers(numbers, calculation)
  new_list = []
  for number in numbers
    # `calculation` is a proc, but we don't care about
    #    its logic: we simply evaluate whatever the
    #    calculation is to the number
    new_list << calculation.call(number)
  end
  new_list
end

Now, we want to use the method map_numbers to take a list of numbers and return a new list with each number multiplied by 2:

# declaring the list
numbers = [1, 2, 3]

# declaring the "calculation" proc, using the "2" curried
#    as we've seen in the previous example
multiply_by_2 = method(:multiply).curry[2]

map_numbers(numbers, multiply_by_2) # => [2, 4, 6]

We can do even better, in a single line, applying other calculations as well:

# multiplying by 2
map_numbers([1, 2, 3], method(:multiply).curry[2])

# multiplying by 4
map_numbers([1, 2, 3], method(:multiply).curry[4])

# multiplying by 42
map_numbers([1, 2, 3], method(:multiply).curry[42])

We could go beyond, supposing we'd have more calculation methods:

map_numbers([1, 2, 5], method(:sum_by).curry[2])
map_numbers([2, 4, 9], method(:square_of).curry[3])

Conclusion

We learned that procs can be passed as arguments to another methods and, optionally, can use curried arguments, making our code appear more declarative.

In the next and last post of this series, we will unblock more fundamentals and introduce blocks.


This content originally appeared on DEV Community and was authored by Leandro Proença


Print Share Comment Cite Upload Translate Updates
APA

Leandro Proença | Sciencx (2021-04-10T23:21:53+00:00) Ruby blocks made easy, part II, curry and procs as arguments. Retrieved from https://www.scien.cx/2021/04/10/ruby-blocks-made-easy-part-ii-curry-and-procs-as-arguments/

MLA
" » Ruby blocks made easy, part II, curry and procs as arguments." Leandro Proença | Sciencx - Saturday April 10, 2021, https://www.scien.cx/2021/04/10/ruby-blocks-made-easy-part-ii-curry-and-procs-as-arguments/
HARVARD
Leandro Proença | Sciencx Saturday April 10, 2021 » Ruby blocks made easy, part II, curry and procs as arguments., viewed ,<https://www.scien.cx/2021/04/10/ruby-blocks-made-easy-part-ii-curry-and-procs-as-arguments/>
VANCOUVER
Leandro Proença | Sciencx - » Ruby blocks made easy, part II, curry and procs as arguments. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/04/10/ruby-blocks-made-easy-part-ii-curry-and-procs-as-arguments/
CHICAGO
" » Ruby blocks made easy, part II, curry and procs as arguments." Leandro Proença | Sciencx - Accessed . https://www.scien.cx/2021/04/10/ruby-blocks-made-easy-part-ii-curry-and-procs-as-arguments/
IEEE
" » Ruby blocks made easy, part II, curry and procs as arguments." Leandro Proença | Sciencx [Online]. Available: https://www.scien.cx/2021/04/10/ruby-blocks-made-easy-part-ii-curry-and-procs-as-arguments/. [Accessed: ]
rf:citation
» Ruby blocks made easy, part II, curry and procs as arguments | Leandro Proença | Sciencx | https://www.scien.cx/2021/04/10/ruby-blocks-made-easy-part-ii-curry-and-procs-as-arguments/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.