📜 ⬆️ ⬇️

Ruby Blocks and Iterators

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)

Source: https://habr.com/ru/post/31526/


All Articles