You can use blocks to implement callbacks, pass pieces of code, and implement iterators.
Blocks are simple pieces of code enclosed in braces or between
do ... end{puts "Hello"} # this is a block
do #
club.enroll (person) # this too
person.socialize #
end #
')
When a block is created, it can be associated with a method call. This is done by placing a block of code at the end of the line containing the method call. For example, in the following code, a block containing
puts "Hi" is associated with a call to the greet method.
greet {puts "Hi"}
If the method has parameters, they are listed before the block:
verbose_greet ("Dave", "loyal customer") {puts "Hi"}
A method can call an associated block one or more times using the
yield expression. It is similar to calling a method that calls a block associated with a method containing
yield .
The following example shows this in action. We define a method that yields two times. Then we call this method, placing the block on the same line after the call (and after listing the method arguments)
def call_block
puts "Start of method"
yield
yield
puts "End of method"
end
call_block {puts "In the block"}
the result will be:
Start of method
In the block
In the block
End of method
Each
yield call prints "In the block".
The code block can be called with parameters, passing them through
yield . Inside the block, simply list the arguments, enclosing them between vertical bars (|).
def call_block
yield ("hello", 99)
end
call_block {| str, num |}
Blocks of code are used everywhere to implement iterators: methods that return sequence elements taken from a certain collection, for example, from an array.
animals =% w (ant bee cat dog elk)
animals.each {| animal | puts animal}
will give:
ant
bee
cat
dog
elk
Inside the
Array class, we would implement the
each iterator as follows, using pseudo-code:
# inside the Array class
def each
for each element # <- pseudo code
yield element
end
end
Most brute-force constructs that are embedded in C or Java in Ruby are simple methods that call the associated blocks zero or more times.
['cat', 'dog', 'horse'] .each {| name | print name, ""}
5.times {print "*"}
3.upto (6) {| i | print i}
('a' .. 'e'). each {| char | print char}
as a result gives us
cat dog horse ***** 3456abcde
We ask object 5 to call the block five times and then ask the object to call the block, passing successive values until they reach value 6. And at the end, the range of values from a to e calls the block using the each method.
All this is a free translation of
Dave Thomas - Programming ruby 2nd edition (The Pragmatic Programmers' Guide)