Understanding Blocks & Procs in Ruby
Tags: ruby, programming, codenewbie, webdev
Published: 2021-06-29 22:02:50

##Blocks
Blocks in Ruby are fairly easy to understand. A block simply contains chunks of code inside and can be passed into methods. If you're familiar with javascript, then a block is equivalent to an anonymous function.

Blocks can be created in two ways, using `{..}` or the `do..end` syntax.
`{..}` is used for single line blocks, while `do..end` syntax is used to encapsulate multiple lines of code.

{% gist https://gist.github.com/ysanchez3d/09e86b2dfe351458e84d838517f493e3 %}

Unlike methods, you should **never** use the `return` keyword inside a block unless you have a really good reason for it. Lets explore why..

{% gist https://gist.github.com/ysanchez3d/556189e0f4fb03c440b50513b1e50cb4 %}

You see, the `return` keyword always belong to methods, so in the second example when `words.map` iterates over the array, it instantly returns the first word it encounters and `yell_words` ends immediately with the output of "LION!" which is not at all what we were expecting. This is a common pitfall for programming newbies, and I surely have been a victim numerous times.<br>
The last thing I want to point out is a shorthand for writing methods that only take 'one' argument that calls a single method. Lets take a peek:

### <a id="shorten-method"></a>{% gist https://gist.github.com/ysanchez3d/4432efa31ca83c0d17f4a619d0bcd167 %}

Lets break this down to understand what all of it means. First, we are calling `Array.select` and passing in the argument `&:odd?`. The `:odd?` part is just a symbol that refers to the `Integer#odd?` *'method'*, which will be called on every element of the array, and `&` is used to convert the *'method'* into a Proc(a normal Ruby object) that can be passed into `select`.
In Ruby it's not possible to pass methods into other methods so we must convert them to Procs in order to do that.

##Procs
A proc is a ruby object that contains a block inside. Through procs, we are able to pass blocks of code around or even save them to a variable. See example below:

{% gist https://gist.github.com/ysanchez3d/8b75c9f9d103d8b88b20b5f00c205a9e %}

Now lets see how we can pass a proc into other methods:

{% gist https://gist.github.com/ysanchez3d/6122c252bd07fd0a8b32e986ba24c90e %}

Notice that we can really alter the behavior of methods by passing in procs that do different things depending on our needs. That's great and all, but can we shorten this a bit? Yes we can!
Ruby allow us to automatically convert blocks into procs. Remember our old friend `&` from the [block's example](#shorten-method), earlier? Lets see how it works:

{% gist https://gist.github.com/ysanchez3d/75f4fad31ef553f298628f78bdc2cf62 %}

It's important to note that since we added `&prc` as the third argument of the method, `combine_and_proc` must always be called with a block or it will throw an error. The block will be taken by the `&prc` argument, and `&` will turn the block into a proc. Now when we call `puts prc.call(word)` inside `combine_and_proc` there will be no errors because `prc` was turned into a proc by Ruby automatically.

To wrap up, i'd like to mention one last thing that our friend `&` can do for us, and that is to turn a proc into a block. Yes, it might sound confusing but it works both ways. Lets take a look:

{% gist https://gist.github.com/ysanchez3d/e9fd97e32e939f3ccb5030751c657362 %}

From the previous example we can gather that `select` takes in a block as its last argument. Then, we created the proc `odds` and passed it like this `[1,2,3].select(odds)` and so we get an error because `odds` is a proc and `select` is expecting a block. So the correct way would be to call select with `&odds)` because `&` will turn the proc into a block right before giving it to the `select` method.

I hope these examples were helpful, and please feel free to alert me of any corrections to the article.

Happy coding  :smiley: