Using heredoc for prettier Ruby code
You can use heredoc Show archive.org snapshot to avoid endlessly long lines of code that nobody can read. Heredoc strings preserve linebreaks and can be used like this:
def long_message
puts(<<-EOT)
Here goes a very long message...
Sincerely,
foobear
EOT
end
<<-EOT
will be somewhat of a placeholder: anything you write in the line after you used it will be its value until you write EOT
in a single line.
You can use any string to flag your heredocs. To be more verbose you can use something else -- your IDE may even be aware of it, for example RubyMine understands <<-SQL
, <<-HTML
, <<-XML
, <<-JSON
, etc and highlights correctly.
Please note:
-
Your string will end with a new-line character (
\n
). -
Your string's lines will be padded with its indentation. The string from the example above will be
" Here goes a very long message...\n Sincerely,\n foobear\n"
. Depending on where you use it, this may or may not be a problem. A possible solution is<<~
(see below). -
You can use regular string interpolation inside heredoc strings:
puts <<-TEXT Dear #{user.name}, ... TEXT
-
Your statement does not have to terminate after the placeholder. Example:
content_tag(:div, <<-TEXT, class: 'example') Dear #{user.name}, ... TEXT
<<~
vs <<-
You can use <<~
(with a tilde) to remove the string's indentation. This will keep any relative indentation in other lines.
<<~TEXT
Hello
Universe!
-foo
TEXT
# => "Hello\nUniverse!\n -foo\n"
# vs:
<<-TEXT
Hello
Universe!
-foo
TEXT
# => " Hello\n Universe!\n -foo\n"
Note that this was introduced with Ruby 2.3. On older Rubies you may use String#strip_heredoc
from ActiveSupport.
<<
vs <<-
(or <<~
)
You may also omit the dash or tilde and just write <<EOT
. If you do this, your terminating sequence must be at the very beginning of the line. It's less pretty and there is rarely a reason to use it:
def foo
puts(<<TEXT)
Hello!
TEXT
end
Multiple heredocs in one line
If you have more than one multi-line string that you want to use in one line, you can just put your heredocs strings below each other. Example:
def long_messages
html_escape(<<-ONE) + '<hr />' + html_escape(<<-TWO)
Here goes my first very long message.
Yeehaw!
ONE
This is the second message which is still long.
It is long indeed.
TWO
end