Intro

I have started using heredocs instead of using string interpolation. I discovered the benefit of this when making some command line games, like tic tac toe, or when outputting long lists comprising multiple elements.

Below are some examples of how we can move away from the standard string interpelotaion pattern.

Examples of standard string building

This is how we are initially taught to build strings in Ruby:

something = "thing"
puts "Here is the " + something + "!"

# output > Here is the thing!

We can do this in another way, getting rid of the + operator to make the strings stick together:

something = "thing"
puts "Here is the #{something}!"

# output > Here is the thing!

This way evaluates whatever is inside the #{} as ruby code. It can be especially useful if we need to do some sort of operation at run time:

standard_price = 10
friends_discount = 4
puts "The final price is #{standard_price - friends_discount} euros!"

# output > The final price is 6 euros!

Warning: something to keep in mind is that interpolation above will not work with single quotes, it requires double quotes.

Heredoc string building

A Heredoc is a way to define a multiline string, while maintaing original indentation and formatting.

Its format looks like this:

Example:


string =
  <<~EOS
   --------------------
     Title of something
     other things here
   --------------------
   EOS
   puts string
# output >
"--------------------
  Title of something
  other things here
--------------------"

Supposing we would like to output a list of items to the terminal, and we would like to format it in a particular way.

We can first consider the below code:

title = 'LIST'
things = 'First thing'
border_line = "--------------------"

puts border_line
puts title + " of something"
puts things + " here"
puts border_line

# output >
"--------------------
LIST of something
First thing here
--------------------"

The above uses puts multiple times, when we could in fact simply build one string object and still be able to leverage the interpolating functionality, perhaps by using annotations. We could then puts just once, as we were able to do above.

We can pass in values to the string using annotations:

SOMETHING =
  <<~EOS<1>
   --------------------
     %<title>s of something
     %<things>s here
   --------------------
   EOS

   result = SOMETHING % {title: 'LIST', things: 'First thing'}

   puts result
   #output >
   "--------------------<2>
     LIST of something
     First thing here
   --------------------"
  1. The tilde (~) means the alignment from the leading side will not be taken into account.
  2. The new line is shown here because we puts.

As a note, the “EOS” is just a namespace and can be called anything that is conveniently descriptive.

The convenience of a heredoc I found to be very apparent when dealing with a structure that is best understood visually, like a board in a game:


BOARD = <<~BOARD
 %s || %s || %s
-------------
 %s || %s || %s
-------------
 %s || %s || %s
BOARD

# In this case, we could leverage a method that inserts the values in for us, in this case I've taken this from a bit of code I have for a game:
def report_board
  BOARD % board.map.with_index(1) { |mark, index| mark || index } << PROMPT[:player] % {player: current_player}
end

The example above is taken from the code for Tic Tac Toe which can be found here.