Use Them, Blockhead! – Learning to Use Ruby Blocks

Blocks are sort of mystical to me. I know very little about the magic that happens under their hood. To aid this lack of knowledge, I decided to write a blog post on blocks hoping that by writing about them I will acquire some knowhow.

As I understand it, blocks are pieces of code that are wrapped by either curly brackets

 array.each{ |element| #some logic here# }

or between a “do” and “end” example:


array.each do |element|
#some logic here#
end

Inside either the curly bracket and the do-end boundaries of the block you write what you want your block to do. So far so good.

Using blocks with methods

If you want to give a method a block you give this method a parameter with an ampersand and call that block inside the method (in Ruby you can do it by using block.call).


def example (&block)
 puts "I am inside the method"
 block.call
end

I order to run this method and its block, pass the block to the method using curly brackets or with “do and end”.


example {} #=> "I am inside the method"

example {puts "Now I am block inside the method"}
 #=> "I am inside the method"
 #=> "Now I am block inside the method"

example do 
 puts "Now I am block inside the method"
end
#=> "I am inside the method"
#=> "Now I am block inside the method"

If you ever wondered why you would use curly brackets to do-end, Ruby sees curly brackets as high priority. An interesting fact that I did not know before researching about blocks before writing this blog post.

Ruby also gives us the the key word

block.given?

if you want to check if a block was passed to the method or not.


def example (&block)
 puts "I am inside the method"
 if block.give?
  block.call
 else
  puts "There was no block passed"
end

example {} 
#=> "I am inside the method"
#=> "There was no block passed"

example {puts "Now I am block inside the method"}
 #=> "I am inside the method"
 #=> "Now I am block inside the method"

Good to Know
An interesting aspect about blocks that I found during my research is that the Ruby interpreter provides us special blocks such as BEGIN and END.


puts "This is an example. The first line of code."

BEGIN {puts "This is the begin of the block"}

END {puts "This is the end of the block"}

#=> "This is the begin of the block"
#=> "This is an example. The first line of code."
#=> "This is the end of the block"

That’s useful to clean up after your program or set the state at the beginning of your program when you’re writing it.

Using Yield
Yield is a way to pass code into the block. It is very similar to block.call


def example (&block)
 puts "I am inside the method"
 yield
end

example {puts "Now I am block inside the method"}
 #=> "I am inside the method"
 #=> "Now I am block inside the method"

The difference between yield and block.call is that yield can pass the code to the block multiple times, thus being great with loops.


def one_to_five 
  i = 1
   while i  Now the number is 1
 #=> Now the number is 2
 #=> Now the number is 3
 #=> Now the number is 4
 #=> Now the number is 5

Yield breaks out of the block, run the code and return that value to the method it is part of.

In the example above I yield from the block, in this case I’m yielding the variable i. I am assigning yield to a number variable and it is returning its value to the method called. Here I am just printing the numbers but I could manipulate the numbers in other ways such as multiplying them by five if I so desired.

Uff… I think this was my longest post so far. I learned much about blocks in Ruby by writing about it. I don’t feel like a total blockhead anymore.
There are other cool stuff related to Ruby blocks such as Procs and Lambdas but these are material for another blog post in the future.

Leave a comment