HEREDOC и его использование в Ruby
Что такое HEREDOC и для чего его используют? Основная цель - написание больших блоков текста (документации) в коде, а также его передача в переменные. HEREDOC - сокращение от "here document".
Чтобы передать HEREDOC переменной, можно использовать привычный синтаксис присваивания:
a = <<HEREDOC Текст документа в переменной HEREDOC puts a
Результат:
Текст документа в переменной
Для более подробного ознакомления с "heredoc" создадим пустой *.rb файл и запишeм в него следующую конструкцию:
def test_heredoc <<HEREDOC Тут у нас будет первая строка документа. А тут вторая. И третья. HEREDOC end
Результат:
Тут у нас будет первая строка документа. А тут вторая. И третья.
В данном примере документация начинается после строки "<< HEREDOC" и заканчивается перед "HEREDOC".
Стоит отметить, что "HEREDOC" вовсе не обязательно писать в верхнем регистре.
Также вместо ключевого слова "HEREDOC" можно использовать любое угодное. "HEREDOC" используется чаще всего программистами, что дает ясно понять, что описывается внутри этой конструкции.
def some_method <<-something Это документация, которая использует "something" вместо "HEREDOC". :) something end puts some_method
Результат запуска 'heredoc.rb':
Это моя документация, которая использует "something" вместо "HEREDOC". :)
Если посмотреть на пример кода метода test_heredoc, показанный в самом начале этой страницы - можно заметить, что не хватает табуляции (отступов на строках, которыми открывается и закрывается "heredoc"). В следующем методе some_method - табуляция присутствует.
Это связано с тем, что конструкция из первого примера "<<" чувствительна к форматированию. Во втором примере конструкция "<<−" (с знаком 'минус' в конце) позволяет форматировать наш код.
"<<−" делает так, что идентификатор конструкции "heredoc" читается так, как если бы он начинался в самом начале строки. Код содержащийся внутри идентификатора читается буквально - и покажет отступы при выводе в терминале.
Чтобы отформатировать текст и избавиться от лишних отступов в начале строк при печати в терминал - нужно использовать символ лямбды "~" после "<<".
Называется эта конструкция - "squiggly".
def some_squiggly_method <<~something Это документация, которая имеет отступы у идентификатора "heredoc". Отступы в начале документации также обрезаются. something end puts some_squiggly_method
Результат:
Это документация, которая имеет отступы у идентификатора "heredoc". Отступы в начале документации также обрезаются.
Обратите внимание, что "squiggly" не просто удаляет все отступы в начале строк, а принимает самый короткий отступ в качестве эталона. Все более длинные отступы будут обрезаны ровно по него. Этот функционал позволяет форматировать документацию и исключать ненужные отступы.
Пример:
def some_squiggly_method <<~something Это документация, которая имеет отступы у идентификатора "heredoc". Отступы в начале документации также обрезаются. Все отступы обрезаются по эту строку. something end puts some_squiggly_method
Вывод программы:
Это документация, которая имеет отступы у идентификатора "heredoc". Отступы в начале документации также обрезаются. Все отступы обрезаются по эту строку.
Пустые строки и строки, состоящие исключительно из буквальных табуляций и пробелов, будут игнорироваться для определения отступов, но экранированные табуляции и пробелы считаются не отступными символами.
"HEREDOC" позволяет нам использовать Ruby-код внутри себя, что позволяет делать документацию динамической:
@rand_number = rand(10) def some_method <<~something Случайное число #{@rand_number} + 1 = #{@rand_number + 1} something end puts some_method
Запустим код:
Случайное число 9 + 1 = 10
Если нам необходимо интерполировать Ruby-код в документации - мы просто возьмем идентификатор нашего "heredoc" в одинарные кавычки:
@rand_number = rand(10) def some_method <<~'something' Случайное число #{@rand_number} + 1 = #{@rand_number + 1} something end puts some_method
Результат:
Случайное число #{@rand_number} + 1 = #{@rand_number + 1}
Обратите внимание, что двойные кавычки можно использовать в конструкции, но они дают такой же результат, как и их полное отсутствие.
Существует способ комбинирования "heredoc", который выглядит так:
def some_method puts(<<~first, <<~second) Текст первого хирдока first Текст второго хирдока second end some_method
Результат:
Текст первого хирдока Текст второго хирдока
Ссылки: RubyDoc