← Back to Ruby Operators

Heredoc

A heredoc (here document) is a way to create a multi-line string in Ruby. It's typically used for creating multi-line messages, SQL queries, or HTML.

A heredoc is defined with an opening symbol of either <<, <<-, or <<~ followed by an identifier (typically all uppercase) that wraps either side of the document.

The base form of a heredoc requires the closing identifier to have no indentation. For that reason, it is not used as much as the other forms.

" msg1 = <<TXT
"   Some text
" More text
> TXT
=> "  Some text\nMore text\n"
> puts msg1
  Some text
More text
=> nil
" msg2 = <<TXT
"   Some text
"   More Text
"   TXT
"   ope, that needs to not be indented
> TXT
=> "  Some text\n  More Text\n  TXT\n  ope, that needs to not be indented\n"

We can see how weird << gets when we have an extra layer of indentation, like we often would in our Ruby programs.

* msg2 = begin
"   <<TXT
"     one
"     two
"     TXT
"   TXT
* TXT
> end
=> "    one\n    two\n    TXT\n  TXT\n"

If we want to preserve the indentation in our heredoc text while allowing our terminating identifier to be placed on whatever we feel is an appropriate column (indentation level), then we want the <<- form:

" msg1 = <<-OTHER
"   one
"   two
> OTHER
=> "  one\n  two\n"
* msg2 = begin
"   <<-OTHER
"     one
"     two
*   OTHER
> end
=> "    one\n    two\n"

If the leading indentation is good for the readability of our program, but not useful in the resulting string, then we should reach for the squiggly heredoc (<<~):

" msg1 = <<~RUBY
"   three
"   four
"   five
> RUBY
=> "three\nfour\nfive\n"
" msg2 = <<~RUBY
"   three
"     four
"       five
> RUBY
=> "three\n  four\n    five\n"

Heredocs without the interpolation

Wrap the initial identifier in single-quotes and you get a heredoc that won't perform string interpolation.

" <<-NUMBERS
"   1
"   #{1 + 1}
"   3
> NUMBERS
=> "  1\n  2\n  3\n"
' <<-'NUMBERS'
'   1
'   #{1 + 1}
'   3
> NUMBERS
=> "  1\n  \#{1 + 1}\n  3\n"

A small detail to notice about how IRB handles these two heredocs is the first is decorated with leading " characters since it is a heredoc that supports interpolation. The second, a single-quote heredoc, is decorated with leading ' characters.

Heredoc Oddities

A single-quoted heredoc with an blank identifier can be created.

" msg1 = <<''
"   hello
"   world
>
=> "  hello\n  world\n"

This 'end-less heredoc' falls under the category of "please don't do this."

There are also backtick heredocs that can execute commands.

puts <<-`HEREDOC`
  cat #{__FILE__}
HEREDOC

For a better explanation and example of that, head over to the backtick page.

References