The curious case of closures || What the heck are procs?

If you have them being called inside a method, they will force the method to return their return valuedef return_from_proc a = Proc.

new { return 10 }.

call puts "This will never be printed.

"endLambdasIn a nutshell, Lambdas are almost the same as Procs.

They’re created and accessed the same way:putser = lambda {|x| puts x}But have two fundamental differences:They check for parity (just being picky with what arguments they take)pnew = Proc.

new {|x, y| puts x + y} lamb = lambda {|x, y| puts x + y} # works fine, printing 6 pnew.

call(2, 4, 11) # throws an ArgumentError lamb.

call(2, 4, 11)And if called inside methods, they allow the execution to continue (they’re polite blokes! )def return_from_lambda a = lambda { return 10 }.

call puts "The lambda returned #{a}, and this will be printed.

"endAnd this makes them all more predictable than Procs!What about when to use them?The whole concept of closures comes mainly from functional programming languages, where all functions are essentially stateless, and because of this, it became a feature to have the ability to pass blocks of code that remember their scope of creation as variables.

Nowadays OO languages don’t have these kind of drawbacks, but most of the programming community believes this kind of behavior is a plus, and many languages have this philosophy better implemented and are becoming sort of hybrid, such as Javascript.

So with that in mind, what can Procs and Lamdas in Ruby be used for?Making your code more DRY, you can quickly create a Proc with a block of code that can be reused throughout your codeclass Account < ApplicationRecordvalidates :password, confirmation: true,unless: Proc.

new { |a| a.

password.

blank?.}endAny situation where it would be handy to access data from other parts of a program to perform some operation, without having to assign that data somewhere else.

For this purpose, Procs are also used in combination with yield statement and the ampersand symbol (&)def contrived(a, &f) # the block can be accessed through f f.

call(a) # but yield also works!.yield(a) end # this works contrived(25) {|x| puts x} # this raises ArgumentError, because &f # isn't really an argument – it's only there # to convert a block contrived(25, lambda {|x| puts x})All in all closures are yet another obscure but useful feature implemented in Ruby that makes it such powerful language!.

. More details

Leave a Reply