adder = Proc.new { |arg1, arg2| arg1 + arg2 }
Procs in Ruby are like anonymous functions. In other words, little packages of code (defined in blocks of {}
or do..end
) that can be passed around as an object.
Proc is actually short for procedure, so when you pass a Proc as an argument to a method, you can think of it as giving the method a list of instructions, as opposed to a particular data structure or value.
adder = -> arg1, arg2 { arg1 + arg2 } # This is called "stabby lambda" syntax
adder = lambda { |arg1, arg2| arg1 + arg2 } # literal syntax
adder.call(1,2)
# => 3
# "do" and "end" still apply
adder = -> arg1, arg2 do
result = arg1 + arg2
result
end
adder.call("a", "b")
# => "ab"
Lambdas are just special types of Procs, with these key differences:
- Argument quantity matters for a lambda. If you pass the wrong amount, you get an error. Not the case with Procs.
- A
return
statement in a lambda returns from the scope of the lambda, while a Procreturn
escapes from the current method.
In my opinion, lambdas are cleaner and stricter, which is a good thing. You are held accountable to the arguments you expect, and the return
is more contained.
doubler = -> number { number * 2 }
ages = [ 15, 32, 13 ]
ages.map(&doubler)
# => [ 30, 64, 26 ]
There's the magic. We set a lambda block to the variable doubler
, which expects a number
argument. We pass this as an argument to ages.map
, with &
declaring doubler
as a Proc type.
words = ["apple", "okay", "not", "yes", "forgettable"]
def longer_than(number)
-> word { word.length > number }
end
words.all?(&longer_than(5))
#=> false
words.all?(&longer_than(2))
#=> true
words.select(&longer_than(3))
#=> ["apple", "okay", "forgettable"]
words.reject(&longer_than(3))
#=> ["not", "yes"]
words.one?(&longer_than(5))
#=> true
Beautifully DRY. Lambdas allow us to reuse logic for any number of higher-order functions like enumerables. (Higher-order functions take functions as arguments).
Try to complete this challenge by calling a lambda in any enumerable you use.