A block is a chunk of code that we put inside do..end or {}. You can use any of the both ways. But multiline block (do..end) is preferred over inline({}) block.
Example of block:
multiline style#
["red", "green", "yellow"].each do |color|
puts "Color: #{color}"
end
inline style#
["red", "green", "yellow"].each{|color| puts "Color: #{color}"}
The output will remain same for both style.
NOTE: Block has no significant use unless passed to a method. We can not assign block to a variable.
Passing block to a method:
def hello
puts "called first"
yield
puts "called at last"
end
hello do
puts "called by yield"
end
Output:
called first
called by yield
called at last
=> nil
yield passes the execution to block. After block is executed, the execution of the method continues.
Method need not to specify the block in its parameters signature. We can pass block to any method, However that needs to be called by yield inside the method. Block won't be executed unless yield executes it or a Proc object is created. Please note if yield is called inside the method we have to pass the block to method otherwise it will throw exception.
NOTE: We can use the block_given? method which returns true/false depending on if a block was passed in to the method or not.
Example 1:
def say_hello
puts "block will not be executed"
end
say_hello {puts "It will not be called"}
block will not be executed
=> nil
Example 2:
def say_hello
puts "yield will not be called if block not passed to method"
yield if block_given?
end
say_hello
yield will not be called if block not passed to method
=> nil
say_hello{puts "now yield will be executed"}
yield will not be called if block not passed to method
now yield will be executed
=> nil
Example 3:
def say_hello
puts "A new proc object will take block as argument and will execute block when called"
proc = Proc.new
proc.call
end
say_hello{puts "block executed !!!"}
A new proc object will take block as argument and will execute block when called
block executed !!!
=> nil
If block is not passed the creating new proc object will throw exception.
Passing block in argument signature of method:
We can pass block to a method as parameter to a method. Method takes last argument as a block. Please note it has to be the last argument, other it will throw exception. Also the block signature needs to have & prefix. It creates a proc object and passed to the method. Proc can be called any time inside the method.
def say_hello(&block)
block.call
end
say_hello{puts "this is passed as a parameter in method"}
this is passed as argument in method
=> nil
Passing parameters to Yield:
We can also pass parameters to yield
def double_me(n)
yield(n)
end
double_me(2){|number| 2*number}
=> 4
As we can see yield returns the last evaluated expression from inside the block.
0 Comment(s)