Вы можете использовать блоки для реализации обратных вызовов, передачи кусков кода и для реализации итераторов.
Блоки представляют собой простые куски кода заключенные в фигурные скобки или между do… end
Когда блок создан его можно ассоциировать с вызовом метода. Это делается помещением блока кода в конец строки содержащей вызов метода. Например, в следующем коде, блок, содержащий puts «Hi» ассоциирован с вызовом метода greet.
Если у метода есть параметры, они перечисляются перед блоком:
Метод может вызвать ассоциированный блок один или несколько раз используя выражение yield. Оно похоже на вызов метода, который вызывает блок, ассоциированный с методом, содержащим yield.
Следующий пример показывает это в действии. Мы определим метод который вызывает yield два раза. Затем вызовем этот метод, поместив блок на той же линии после вызова (и после перечисления аргументов метода)
результатом будет:
Каждый вызов yield выводит на печать «In the block».
Блок кода можно вызывать с параметрами, передавая их через yield. Внутри блока просто перечислите аргументы, заключив их между вертикальными чертами (|).
Блоки кода использеются повсюду для реализации итераторов: методы которые возвращают элементы последовательности взятые из некоторой коллекции, например, из массива.
даст:
Внутри класса Array мы бы реализовали итератор each следующим образом, используя псевдо-код:
Большинство конструкций перебора которые встроены в C или Java в Руби являются простыми методами, вызывающими ассоциированные блоки ноль или более раз.
в результате дает нам
Мы просим объект 5 вызвать блок пять раз и затем просим объект вызвать блок, передавая последовательные значения пока они не достигнут значения 6. И в конце диапазон величин от a до e вызывает блок используя метод each.
Все это — вольный перевод Dave Thomas — Programming ruby 2nd edition (The Pragmatic Programmers' Guide)
Блоки представляют собой простые куски кода заключенные в фигурные скобки или между do… end
{ puts «Hello»} #это блок
do #
club.enroll( person) # и это тоже
person.socialize #
end #
Когда блок создан его можно ассоциировать с вызовом метода. Это делается помещением блока кода в конец строки содержащей вызов метода. Например, в следующем коде, блок, содержащий puts «Hi» ассоциирован с вызовом метода greet.
greet { puts «Hi» }
Если у метода есть параметры, они перечисляются перед блоком:
verbose_greet(«Dave», «loyal customer») {puts «Hi»}
Метод может вызвать ассоциированный блок один или несколько раз используя выражение yield. Оно похоже на вызов метода, который вызывает блок, ассоциированный с методом, содержащим yield.
Следующий пример показывает это в действии. Мы определим метод который вызывает yield два раза. Затем вызовем этот метод, поместив блок на той же линии после вызова (и после перечисления аргументов метода)
def call_block
puts «Start of method»
yield
yield
puts «End of method»
end
call_block { puts «In the block» }
результатом будет:
Start of method
In the block
In the block
End of method
Каждый вызов yield выводит на печать «In the block».
Блок кода можно вызывать с параметрами, передавая их через yield. Внутри блока просто перечислите аргументы, заключив их между вертикальными чертами (|).
def call_block
yield(«hello», 99)
end
call_block {|str, num|}
Блоки кода использеются повсюду для реализации итераторов: методы которые возвращают элементы последовательности взятые из некоторой коллекции, например, из массива.
animals = %w( ant bee cat dog elk )
animals.each {|animal| puts animal }
даст:
ant
bee
cat
dog
elk
Внутри класса Array мы бы реализовали итератор each следующим образом, используя псевдо-код:
# внутри класса Array
def each
for each element # < — псевдо код
yield element
end
end
Большинство конструкций перебора которые встроены в C или Java в Руби являются простыми методами, вызывающими ассоциированные блоки ноль или более раз.
[ 'cat', 'dog', 'horse' ].each { |name| print name, " "}
5.times { print "*" }
3.upto(6) { |i| print i }
('a'..'e').each { |char| print char }
в результате дает нам
cat dog horse *****3456abcde
Мы просим объект 5 вызвать блок пять раз и затем просим объект вызвать блок, передавая последовательные значения пока они не достигнут значения 6. И в конце диапазон величин от a до e вызывает блок используя метод each.
Все это — вольный перевод Dave Thomas — Programming ruby 2nd edition (The Pragmatic Programmers' Guide)