Sage-Code Laboratory
index<--

Ruby Blocks

There is somesing exotic in Ruby that makes the language intresting to use. These are called "blocks". A block consist of a chunk of code, enclosed in curly brackets. It allows you to group code into a standalone unit that you can use as a method argument. Using blocks is a way of injecting code inside a method, dinamicly changing its behaviour without modifiyng the method.

Pattern: for single line syntax.

block_name { statement } 

Pattern: for multy line syntax.

block_name 
do
   statement1
   statement2
   ..........
end

Note:Both syntax patterns are doing the same thing. As a general rule of thumb, it’s better to use the do/end version if your code has more than one line, just to make it easier to read.

Using Blocks

A method can call a block once or several times using yield keyword. This keyword require the method to be called using a block after the argument list. When yield is used, the method require a block. If the block do not exist in the method call, you will end-up with an error.

# define a method that require a block
# define a method that require a block
def method
  yield
end  

#call method with block arguments
method {puts "first call"}  
method {puts "second call"}  

Block Parameters

Blocks can have parameters. The syntax to define parammeters is different from methods. Parameters are enclosed between two vertical lines like in the pattern below:

block_name {|a, b| statement }

Example:

# define a method that require a block
def demo
  yield('hello', 100)  
end  

#call method with block arguments
demo {|str, num| puts str + '-' + num.to_s}  
demo {|str, num| puts str + ':' + num.to_s}  

Result Value

A code block can return a value. It is the value of the last expression evaluated in the code block. This is made available inside the associated method as result of yield that is used to call the block. It can be captured using the assign "=" statement.

Example:

# define a method that require a block
def eval(p1, p2)
  result = yield(p1, p2)  
  print "result = ", result, "\n"
end  

#call method with block arguments
eval(4, 3) {|a, b| a + b}  
eval(4, 3) {|a, b| a - b}  
eval(4, 3) {|a, b| a * b}  

Output:

result = 7
result = 1
result = 12

Special Blocks

In a Ruby script you can define two special named blocks: BEGIN and END Blocks The BEGIN blocks are run automatically when script is being loaded. The END blocks are executed after the program has finished executing. You can create more than one of BEGIN blocks and more than one END blkcs.

#!/usr/bin/ruby

BEGIN { 
   # BEGIN block code 
   puts "BEGIN code block"
} 

END { 
   # END block code 
   puts "END code block"
}

# main code (do not use keyword MAIN 
puts "main code block"

HTML Wrapper

Blocks are the good candidates whenever you need to wrap dynamic code within some static code. For example if you want to surrond some text with html tags. The text is the the dynamic part and the tags are the static part.

#demo: wrapper method
def wrap_text(tag)
  "<#{tag}>" + yield + "</#{tag}>"
end

# create html elements
str   = wrap_text("h1"){ "Page header"} 
str  += wrap_text("p") { "This is a paragraph."} 

# wrap the html document
page  = wrap_text("html") {str}
print page 
<html><h1>Page header</h1><p>This is a paragraph.</p></html>

Read next: Classes