Jacklynn
Jacklynn

Reputation: 1553

Semantic differences between percent literals and herdocs in Ruby?

Looking at some documentation, I saw a multiline string defined using a percent literal:

command %Q{
    do this;
    do that;
}

In the past, I've always used heredocs when I needed multiline strings:

command <<-heredoc
    echo "stuff" | do stuff;
heredoc

What are the semantic differences between them? Is there any reason why I would want to use %Q and not a heredoc?

Upvotes: 2

Views: 637

Answers (3)

Max
Max

Reputation: 22325

There isn't really a semantic difference, and it doesn't have to do with multiline strings either. All strings can be multiline in Ruby. These are all the same string:

'a
b
'

"a
b
"

%Q{a
b
}

<<-heredoc
a
b
heredoc

The question of which to use is decided by whether you need interpolation and the convenience of escaping characters. For example:

  1. Do you need interpolation? If not then '' or %q()
  2. Will there be lots of quote characters to escape? Then use %Q()
  3. Do you want to write a lot of text without thinking about escaping characters? Use heredocs.

Upvotes: 1

Patrick Oscity
Patrick Oscity

Reputation: 54684

There's a funky trick that you can use with heredocs: the first line can be used as if it was a complete string. For example, all of the following examples are valid Ruby code:

puts(<<-EOS)
  Hello, world!
EOS

<<-EOS.upcase
  Hello, world!
EOS

puts(<<-EOS.upcase)
  Hello, world!
EOS

However, you will not find that very often in the wild. Other than that, they are the same as double quoted strings or %Q{} and %{} literals, except that you can choose multi-character delimiters. This comes in handy when all of the possible percent literal delimiters may occur in the string. This especially applies to long strings.

Upvotes: 2

mjgpy3
mjgpy3

Reputation: 8947

I tend to evaluate how much text is being used when deciding which to use.

I use %Q when there's not a lot of text (for example, a single line), e.g. %Q|foobar|. The value that %Q provides, is it allows you to easily mix quotes, e.g.

%Q|"Get a Job" ~Mom's words|

I use "heredoc"s when there is a lot of text that spans multiple lines.

For example, suppose you're pasting a lot of text into a REPL (like the content of a YAML file). Unless you traverse the whole file, you can't be certain whether or not you will have a conflict with whatever %Q separator you have chosen. With a "heredoc" you just use some really obscure piece of text that you're fairly certain will not have a conflict, e.g.

<<-BatMobilePrettyObscure
... Lots of text ...
BatMobilePrettyObscure

As far as I know, semantically, there are just a few small differences:

  • %Q can only use one character to delimit strings
  • %Q can be multi-line or single-line
  • "heredoc"s must be Multi-line, with the closing "heredoc" standing alone
  • %Q delimiters can be "mashed" up against their strings, e.g. %Q|foobar|

Upvotes: 3

Related Questions