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
returnstatement in a lambda returns from the scope of the lambda, while a Procreturnescapes 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))
#=> trueBeautifully 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.