Одной из уникальных особенностей языков программирования Ruby являются блоки. Я никогда не слышал о блоках до того, как начал изучать Ruby, и мне потребовалось некоторое время, чтобы понять их использование и назначение. Это мощная функция, которая широко используется.
Вот самый простой пример использования блока в Ruby. Приведенный ниже код выполняет итерацию по каждому элементу в массиве названий книг и печатает его.
books = ['To Kill a Mockingbird', '1984', 'The Catcher in the Rye'] books.each do |book| puts book end # Outputs: # To Kill a Mockingbird # 1984 # The Catcher in the Rye
По сути, блок передает параметр (или параметры) и позволяет вам что-то с ним делать.
Блоки
— начинаются с do
— принимают один или несколько параметров
— делают что-то с параметрами
— заканчивают end
Параметры
Параметры — это просто аргументы, которые вы принимаете. Вы можете назвать их как угодно.
В приведенном выше примере мы назвали наш параметр book
, но мы могли бы легко назвать его как угодно.
books = ['To Kill a Mockingbird', '1984', 'The Catcher in the Rye'] books.each do |book_title| puts book_title end # Outputs: # To Kill a Mockingbird # 1984 # The Catcher in the Rye
Какое бы имя вы ни приняли для своего параметра, это имя переменной, которое вы используете в своем блоке.
Сокращенный синтаксис
Ruby также предоставляет сокращенный синтаксис для блоков, который позволяет вам писать простые однострочники.
Тот же блок сверху можно записать следующим образом.
books = ['To Kill a Mockingbird', '1984', 'The Catcher in the Rye'] books.each { |book| puts book } # Outputs: # To Kill a Mockingbird # 1984 # The Catcher in the Rye
Написание собственных блоков
Вы не ограничены использованием уже существующих блоков. Вы можете написать свой собственный.
Скажем, у вас есть метод инициализации для класса ApiClient
. Он установит обычную конфигурацию по умолчанию, но вы хотите предоставить способ настроить конфигурацию, если это необходимо. Например, кто-то может захотеть добавить дополнительный заголовок, который должен присутствовать, когда ApiClient
делает запросы.
Если вы хотите использовать значение по умолчанию, вы должны сделать следующее, не передавая блок.
client = ApiClient.new
Однако что, если вы хотите начать с настроек по умолчанию, а затем дополнительно настроить конфигурацию? Может быть, что-то вроде:
api_key = 'neXYWWxojNJxckDJxSLKjW2EurdI84R8ZZucMW89wHXmFOF13udOz' client = ApiClient.new do |config| config.add_header('X-API-Key', api_key) end
Как будет выглядеть наш метод initialize
?
class ApiClient # ... def initialize @config = ApiConfig.new yield @config if block_given? self end #... end
Обратите внимание на часть yield
. Это то, что позволяет вам прикрепить блок к вашему методу. Вы можете передать любое количество аргументов методу yield
. Эти аргументы будут параметрами, переданными блоку.
Используйте block_given?
, чтобы проверить, был ли задан блок, если вы хотите, чтобы он был необязательным.