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*.

## Top comments (0)