В этом посте мы рассмотрим блоки в Ruby.
- Блоки
- Как они используются
- Как включить их в свои собственные методы
Некоторые люди отбрасываются блоки в Ruby, потому что в других языках нет блоков. Но просто подумайте о них как о кусках кода, который выполняется. Вы передаете их между фигурными скобками ({}
) или ключевыми словами do
и end
, и они передаются методам в качестве последнего параметра.
Конвенция:
- Используйте
{}
, когда содержимое блока является одной строкой - Используйте
do
иend
, когда содержимое блока занимает несколько строк
Блоки часто используются в качестве итераторов. Также они могут принимать аргументы.
1.times { puts "Привет, мир!" }
# => "Привет, мир!"
2.times do |index|
if index > 0
puts index
end
end
# => 1
2.times { |index| puts index if index > 0 }
# => 1
Программирование с блоками
Есть два пути, чтобы настроить блок в вашем собственном методе.
Неявный:
- Используйте
block_given?
, чтобы посмотреть был ли задан блок - Используйте
yield
, чтобы “вызвать” блок
Явный:
- Используйте
&
перед последним “параметром” - Используйте метод
call
, чтобы вызвать блок
Неявный
Вы должны проверить задан ли блок, в другом случае будет выдано исключение.
def two_times_implicit
return "Нет блока" unless block_given?
yield
yield
end
puts two_times_implicit { print "Привет " } # => "Привет Привет"
puts two_times_implicit # => Нет блока
Явный
Явный способ очень похож, но вы явным образом заявляете, что этот метод может принимать блок.
Здесь вы должны проверить является ли блок nil?
.
def two_times_explicit (&i_am_a_block)
return "Нет блока" if i_am_a_block.nil?
i_am_a_block.call
i_am_a_block.call
end
puts two_times_explicit # => Нет блока
two_times_explicit { puts "Привет" } # => Привет
# => Привет
Эти два способа очень похожи, и это зависит от вкуса, какой вы хотите использовать.
В итоге
Таким образом, блоки — это просто код, который вы передаете в методы. И еще раз, может уйти некоторое время чтобы привыкнуть к ним, потому что они не очень распостранены в других языках.
И если вы хотите включить блоки в свои методы, вы можете сделать это неявно, вроде притворяясь что блок не существует, и отдавая его если он существует, или вы можете явно указать его в своем методе и затем вызвать его, убедившись что он не является nil.