What is it? How does it work?

Ruby code blocks are definitely one of the coolest features of Ruby. Blocks are just chunk of code.

In other programming languages, they may refer to it as closures.

 

Blocks

Ruby blocks are little anonymous functions that can be passed into methods.

Anonymous function:- An anonymous functions are functions that were declared without any named identifier to reference it.

We may consider JavaScript as an example to better understand this concept:

Normal function definition in js

function sayHello(){ 

  alert(“Hello World”)

}

sayHello();

Anonymous function definition in js

var anony = function(){

  alert(“Hello World”)

}

anony();

In Ruby:

Blocks are enclosed in a do/end statement or between {}. Curly braces are preferred for single line blocks. And do / end is used for multi-line blocks.

If you have ever used each method, then you have used blocks

[“a”,”b”,”c”].each {|char| puts char}

or

[“a”,”b”,”c”].each do |char|

  puts char

end

So Now the question arises that how a method works with the block and how it can know that a block is given.

Here yield comes in picture.

When yield the code inside the block will be executed.

Ex:-

def block_taking_method

  puts “first puts called”

  yield

end

block_taking_method {puts “second puts coming as block”}

when above code is executed it will output as follows

#first puts called

#second puts coming as block

If you reverse the order and put yield before then the out will also be reversed as yield will execute the block first and the rest of the code inside the method.

If you put yield multiple times the same code will be executed multiple times.

We can pass any number of arguments to yield also. These arguments can be used by the block then.

def multiply_with_argu

  yield 1

  yield 2

  yield 3

end

multiply_with_argu { |numb| puts numb * 10 }

#10

#20

#30

Note that the code in the block is not executed at the time it is encountered by the Ruby interpreter. Instead, Ruby remembers the context in which the block appears and then enters the method.

A block’s return value (like that of a method) is the value of the last expression evaluated in the code block. This return value is made available inside the method; it comes through as the return value of yield.

Blocks can be explicitly called using call method as follows

def explicitly_calling(&block)

  block.call

end

explicitly calling { puts “Explicitly calling block”}

Now, what would happen if you call yield or call with an actual block given?

If you use yield or call without any block it will give u no block given (yield) error.

So for better error handling, we can use “block_given?” method which is provided by Ruby.

“block_given?” method returns Boolean. So we can use it like below

def some_task_with_block

  return “No block given” unless block_given?

  yield

end

This concept of the block is very useful when working with metaprogramming in ruby.