As you know, I am a big believer in knowing the basics. I find it is especially valuable to go back to the fundamentals of whatever skill you’re trying to master periodically, as you gain more experience. Somehow you’re always able to extract something valuable from the experience due to the extra insight you’ve acquired along the way. Recently I’ve been looking more closely at some Ruby concepts that I may have glossed over when I was learning the language initially, so I will likely be writing about this in some of my upcoming posts. I thought I would begin with one of the most powerful features of Ruby – procs (and lambdas :)).

What’s So Good About Procs?

You know how everything in Ruby is an object, well, as it turns out that’s not quite true. Ruby blocks are not objects! We can discuss the implications of that, but let’s refrain, accept it as fact and move on. So, blocks are not objects, but you can turn them into objects without too much trouble. We do this by wrapping our block in an instance of the Proc class (more on this shortly). This is really great since it turns our block into a first class function, which in turn allows Ruby to support closures and once a language has closures, you can do all sorts of interesting things like making use of various functional concepts. That however is a story for another time, before we dive deep into those areas, let us really understand how Procs work.

Procs And Lambdas In Detail

There are three ways to create a Proc object in Ruby. Well, actually there are four ways, but the last one is implicit. Here they are:

Using Proc.new. This is the standard way to create any object, you simply need to pass in a block and you will get back a Proc object which will run the code in the block when you invoke its call method. ruby proc_object = Proc.new {puts "I am a proc object"} proc_object.call [email protected]:~/tmp$ ruby a.rb I am a proc object Using the proc method in the Kernel module. Being in the Kernel module, this method is globally available. It is basically equivalent to Proc.new in Ruby 1.9, but not in Ruby 1.8. In Ruby 1.8 the proc method is equivalent to lambda. As you may have guessed there is a difference between procs and lambdas (see below), so you need to be aware of whether you’re using Ruby 1.8 or 1.9. If you’re using 1.9 there is a way to find out if you’re dealing with a proc or a lambda. The Proc object lambda? method: ruby proc_object = proc {puts "Hello from inside the proc"} proc_object.call puts "Is proc_object a lambda - #{proc_object.lambda?}" [email protected]:~/tmp$ rvm use 1.9.1 Using ruby 1.9.1 p378 [email protected]:~/tmp$ ruby a.rb Hello from inside the proc Is proc_object a lambda - false If you’re in 1.8 this method will not exist at all. By the way, did you notice how I had to switch Rubies and was able to do so painlessly through the awesome power of RVM, hope you’re already using it. As far as I am concerned, if you need to switch between different versions of Ruby, don’t bother with the proc method, just use Proc.new and you will never have an issue.

Using the Kernel lambda method . Once again, this is globally available being in the Kernel module, using this method will create a Proc object, but it will be a lambda as opposed to a proc (if you really need to know what the differences are at this point you can skip to the explanation :)). ruby proc_object = lambda {puts "Hello from inside the proc"} proc_object.call puts "Is proc_object a lambda - #{proc_object.lambda?}" [email protected]:~/tmp$ ruby a.rb Hello from inside the proc Is proc_object a lambda - true

The implicit way. When you write a method which will accept a block, there are two ways you can go about it. The first is to simply use the yield keyword inside your method. If there is a yield in a method, but there is no block you will get an error. ```ruby def my_method puts “hello method” yield end

my_method {puts “hello block”} my_method```

hello method hello block hello method a.rb:7:in my_method': no block given (yield) (LocalJumpError) from a.rb:11:in <main>'

1 2 3 The other way is to use a special parameter in your method parameter list. This special parameter can have the same name but you will need to precede it with an ampersand. The block you pass into this method will then be associated with this parameter, you will infact no longer have a block – it will be a Proc object. You will simply need to call the Proc _call_ method to execute the code in the block you passed in. The difference is, you can now return your block (_or rather the Proc object_) as the return value of the method, thereby getting your hands on a Proc object without having to use any of the above three methods explicitly. ```ruby

def my_method(&my_block) puts “hello method” my_block.call my_block end

block_var = my_method {puts “hello block”} block_var.call```

hello method hello block hello block

1 2 3 4 5 6 7 Those are all the different ways to get a Proc object in Ruby (_either a proc or a lambda_). > ### Fun And Interesting Trivia About Procs And Lambdas > > If you have a method to which you pass a block, but instead of calling _yield_, you call _Proc.new_ without giving it a block of its own, it will return a proc that represents the block you passed in to the method e.g.: > > ```ruby

def some_method Proc.new end

my_proc = some_method{puts “I am a happy proc”} my_proc.call > > <pre>[email protected]:~/tmp$ ruby a.rb I am a happy proc</pre> > > **In Ruby 1.9, there is actually another way to create lambdas**. It isn't really a different way, it is simply some syntactic sugar, but it is crazy looking, so worth knowing :). The normal way to create a lambda is using the _lambda_ keyword, and if you want your lambda to take parameters, you simply pass them in the normal block way e.g.: > > ruby normal_lambda = lambda {|param1, param2| puts “param1: #{param1} and param2: #{param2}“} normal_lambda.call(10, 20) > > <pre>[email protected]:~/tmp$ ruby a.rb param1: 10 and param2: 20</pre> > > With the new syntax it is slightly different. We replace the lambda method with the **->** method (_as in minus followed by greater than sign_). The <a href="http://www.skorks.com/2009/08/method-arguments-in-ruby/" target="_blank">parameters</a> move out of the block, and move into some brackets right after the **->** method (_so they look like method parameters, but in reality are still block parameters_). Everything else is the same, so our previous example would look like: > > ruby normal_lambda = ->(param1, param2) {puts “param1: #{param1} and param2: #{param2}“} normal_lambda.call(10, 20)``` > >

[email protected]:~/tmp$ ruby a.rb param1: 10 and param2: 20

1 2 3 4 5 6 7 8 9 ## Procs Are First Class (Functions That Is) <p style="text-align: center;"> <img align="middle" alt="First class" class="aligncenter size-full wp-image-1832" src="http://www.skorks.com/wp-content/uploads/2010/05/first_class.jpg" style="width: 322px; height: 214px;" title="First class" srcset="https://www.skorks.com/wp-content/uploads/2010/05/first_class.jpg 500w, https://www.skorks.com/wp-content/uploads/2010/05/first_class-300x199.jpg 300w" sizes="(max-width: 500px) 100vw, 500px" /> </p> Once we have created our first class function (_in Proc form_), there are a few things we may want to do with it, such as calling it or comparing it to another Proc. As usual, Ruby makes all of this interesting. Let's look at Proc equality first. You can compare procs or lambdas to each other, using the == method (_just like with any other object_). Unlike many other objects though, defining exactly the same proc twice will not make them equal. For example: ```ruby

> > Everything still works fine (in Ruby 1.9, don’t try this in 1.8), but if you’re using Netbeans, this syntax is way too crazy for it and it will barf all over itself. This syntax is an interesting curiosity, but(especially if you’re using Netbeans) and that of everyone else who has to read your code later.

string1 = “blah” string2 = “blah”

puts “#{string1 == string2}”

proc1 = Proc.new{“blah”} proc2 = Proc.new{“blah”}

puts “#{proc1 == proc2}”```

String are equal? - true Procs are equal? - false

1 2 3 There are only two ways that two procs or lambdas will be equal to each other. One way is to define two really simple procs that have the same object in them e.g.: ```ruby

proc1 = Proc.new{string1} proc2 = Proc.new{string1}

puts “Procs are equal? - #{proc1 == proc2}”```

Procs are equal? - true

1 2 3 This is not really very useful. The other way that two procs will ever be equal is if they are clones of each other (_one was created by using the clone or dup method on the other_). ```ruby

proc1 = Proc.new{|x|“blah1”*x} proc2 = proc1.dup

puts “Procs are equal? - #{proc1 == proc2}”```

Procs are equal? - true

1 2 3 Let us now look at executing procs. We have already seen the call method; this is the most common way to execute a proc or lambda. ```ruby

puts Proc.new{|x|“blah1”*x}.call(2)```

blah1blah1

1 2 3 But, there are actually two other ways. The first is to use the array syntax, this works in both Ruby 1.8 and 1.9: ```ruby

puts Proc.new{|x|“blah1”*x}(#difference)```

blah1blah1

1 2 3 The other is the dot syntax, which only works in 1.9. ```ruby

puts Proc.new{|x|“blah1”*x}.(2)```

blah1blah1

1 2 3 This syntax being 1.9 only will once again cause Netbeans to barf all over itself :). Both of those ways are nice and succinct, but **I still recommend you use _call_; it is not that much longer and is much more readable, both for yourself and for others**. The array syntax could be especially confusing, consider: ```ruby

some_var[2,3]```

1 2 3 4 5 6 7 That could refer to an array, a string, a proc – without context it's a bit too ambiguous for my tastes, stick to _call_. > ### Even More Trivia About Procs And Lambdas > > You may not know this, but procs and lambdas have an _arity_ method which allows you to find out how many arguments a Proc objects expects to receive (_<a href="http://ruby-doc.org/core/classes/Method.html" target="_blank">Method</a> objects also have this method_). For example: > > ```ruby

my_proc = Proc.new{|x|“blah1”*x} puts “I need #{my_proc.arity} arguments” > > <pre>[email protected]:~/tmp$ ruby a.rb I need 1 arguments</pre> > > Pretty simple – the fun bit starts when the block you use to create the proc expects an arbitrary number of arguments (_or requires some, but sponges up the rest using a * prefixed final parameter_) e.g.: > > ruby my_proc = Proc.new{|x, *rest|“blah1 #{x} - #{rest}”} puts “I need #{my_proc.arity} arguments” > > <pre>[email protected]:~/tmp$ ruby a.rb I need -2 arguments</pre> > > What the hell? **When you get a negative number for you arity, it means there is potentially an arbitrary number of arguments involved**. In this case, all you can do is find out how many arguments are required (_the rest will be optional_). You do this by using the **~** operator on the return value of the arity method: > > ruby my_proc = Proc.new{|x, *rest|“blah1 #{x} - #{rest}”} puts “I actually require #{~my_proc.arity} arguments, the rest are optional”``` > >

[email protected]:~/tmp$ ruby a.rb I actually require 1 arguments, the rest are optional

1 2 3 4 5 6 7 <a name="difference"></a> ## So What IS The Difference Between Procs And Lambdas? It took a while, but we finally got here. Long story short, **the real difference between procs and lambdas has everything to do with control flow keywords**. I am talking about return, raise, break, redo, retry etc. – those control words. Let's say you have a return statement in a proc. When you call your proc, it will not only dump you out of it, but will also return from the enclosing method e.g.: ```ruby

> > I reckon that’s interesting stuff to know, it won’t save your life on a daily basis, but there will be that one time when knowing this will make you look like an absolute superstar :).

def my_method puts “before proc” my_proc = Proc.new do puts “inside proc” return end my_proc.call puts “after proc” end

my_method```

before proc inside proc

1 2 3 The final _puts_ in the method, was never executed, since when we called our proc, the return within it dumped us out of the method. If, however, we convert our proc to a lambda, we get the following: ```ruby

def my_method puts “before proc” my_proc = lambda do puts “inside proc” return end my_proc.call puts “after proc” end

my_method```

before proc inside proc after proc

1 2 3 The return within the lambda only dumps us out of the lambda itself and the enclosing method continues executing. The way control flow keywords are treated within procs and lambdas is the main difference between them. Or rather, the way that the _return_ keyword and the _break_ keyword are treated is the difference since most of the others are treated in exactly the same way in both procs and lambdas. Let's have a look at _break_. If you have a break keyword within a lambda it is treated just like a return: ```ruby

def my_method puts “before proc” my_proc = lambda do puts “inside proc” break end my_proc.call puts “after proc” end

my_method```

before proc inside proc after proc

1 2 3 However, if we change the lambda to a proc: ```ruby

def my_method puts “before proc” my_proc = proc do puts “inside proc” break end my_proc.call puts “after proc” end

my_method```

before proc inside proc a.rb:64:in block in my_method': break from proc-closure (LocalJumpError) from a.rb:66:in call' from a.rb:66:in my_method' from a.rb:70:in <main>'

1 2 3 We get a LocalJumpError, what happened? Well, the break keyword is used to break out of iteration, and we didn't have an iterator around our proc, so we couldn't break out of anything, so Ruby tries to punish us with an error. If we put an iterator around our proc, everything would be fine: ```ruby

def my_method puts “before proc” my_proc = proc do puts “inside proc” break end [1,2,3].each {my_proc.call} puts “after proc” end

my_method```

before proc inside proc after proc