Question
In Ruby, is there a cleaner way to write a long string across multiple lines without manually concatenating each part with +?
For example, instead of writing:
conn.exec 'select attr1, attr2, attr3, attr4, attr5, attr6, attr7 ' +
'from table1, table2, table3, etc, etc, etc, etc, etc, ' +
'where etc etc etc etc etc etc etc etc etc etc etc etc etc'
is there a way to split the string over multiple lines while still treating it as one string automatically?
I am especially looking for a more readable way to format long SQL statements.
Short Answer
By the end of this page, you will understand how Ruby handles multi-line strings and how to write long text more cleanly without using repeated + concatenation. You will see practical options such as heredocs, backslash line continuation, and adjacent string literals, with a focus on readable SQL queries.
Concept
Ruby gives you several ways to represent long strings across multiple lines. This matters because long strings appear often in real programs: SQL queries, HTML templates, error messages, JSON payloads, and command-line output.
The core idea is that you do not always need to build a long string with +. In many cases, Ruby lets you write text in a more readable form.
The most useful approaches are:
- Heredoc: best for long multi-line text such as SQL or templates
- Adjacent string literals: Ruby can combine neighboring string literals automatically in some contexts
- Backslash line continuation: keeps the string logically on one line in Ruby code
For SQL specifically, heredoc is usually the clearest choice because it preserves formatting and makes the query easier to read and maintain.
A key thing to remember is that multi-line source code and multi-line string content are not always the same:
- Sometimes you want the Ruby code on multiple lines, but the final string should be one line
- Sometimes you want the final string itself to contain line breaks
Choosing the right approach depends on which of those you want.
Mental Model
Think of a string like a note you want to write on paper.
- Using
+is like cutting the note into pieces and taping them together. - Using a heredoc is like writing the whole note naturally in one block.
- Using adjacent literals is like putting several note fragments next to each other and letting Ruby combine them.
If the content is naturally long, like an SQL query, heredoc is usually the most natural way to write it.
Syntax and Examples
1. Heredoc
A heredoc lets you write a string block over multiple lines.
sql = <<~SQL
SELECT attr1, attr2, attr3, attr4, attr5, attr6, attr7
FROM table1, table2, table3
WHERE table1.id = table2.table1_id
SQL
conn.exec(sql)
Why this is useful
- Very readable
- Great for SQL, HTML, JSON, and long messages
- Keeps the formatting close to how the final text should look
<<~SQL also removes common indentation, so your code can stay neatly indented.
2. Adjacent string literals
Ruby can join string literals written next to each other.
sql = 'SELECT attr1, attr2, attr3 '
'FROM table1, table2, table3 '
'WHERE table1.id = table2.table1_id'
conn.exec(sql)
This is much cleaner than using + repeatedly.
3. Backslash line continuation
If you want one logical string split across lines in code, you can continue the expression with \.
sql = 'SELECT attr1, attr2, attr3 ' \
'FROM table1, table2, table3 ' \
'WHERE table1.id = table2.table1_id'
This still relies on separate string literals, but the line continuation makes the code valid across lines.
Step by Step Execution
Consider this example:
sql = 'SELECT name, email '
'FROM users '
'WHERE active = true'
puts sql
Step by step
-
Ruby reads the first string literal:
'SELECT name, email ' -
Ruby sees another string literal immediately after it:
'FROM users ' -
Ruby combines them into one string.
-
Ruby reads the third string literal:
'WHERE active = true' -
Ruby combines that too.
-
The final value of
sqlbecomes:SELECT name, email FROM users WHERE active = true -
puts sqlprints the full combined string.
Heredoc trace
Now compare that with a heredoc:
Real World Use Cases
Multi-line strings are common in real Ruby programs.
SQL queries
query = <<~SQL
SELECT id, name, email
FROM users
WHERE active = true
ORDER BY name
SQL
Used in:
- database scripts
- reporting tools
- background jobs
- Rails apps with raw SQL
HTML or email templates
html = <<~HTML
<h1>Welcome</h1>
<p>Your account is ready.</p>
HTML
Used in:
- email generation
- simple server responses
- templated notifications
JSON payloads
payload = <<~JSON
{
"event": "signup",
"status": "success"
}
JSON
Used in:
- API testing
- fixtures
- mock requests
Shell commands
command = <<~CMD
echo "Starting"
echo "Done"
CMD
Used in:
- automation scripts
- deployment helpers
- build tools
Real Codebase Usage
In real projects, developers usually choose the style that makes intent most obvious.
Common patterns
1. Heredoc for long SQL
sql = <<~SQL
SELECT users.id, users.name
FROM users
WHERE users.active = true
SQL
This is common because SQL is easier to review when formatted like SQL.
2. Assign once, pass later
sql = <<~SQL
SELECT *
FROM orders
WHERE status = 'pending'
SQL
result = conn.exec(sql)
This helps with:
- debugging
- logging
- testing
- reusing the query
3. Inline heredoc for one-off calls
conn.exec(<<~SQL)
SELECT *
FROM products
WHERE in_stock = true
SQL
Good for short one-use queries.
4. Interpolation with care
table_name = 'users'
sql = <<~SQL
SELECT *
FROM #{table_name}
SQL
Useful, but developers should be careful with untrusted input. For values, parameterized queries are safer than building SQL manually.
5. Guarding readability
If a string becomes too long or complex, developers usually:
Common Mistakes
1. Using + everywhere
This works, but it is noisy and harder to maintain.
sql = 'SELECT * ' +
'FROM users ' +
'WHERE active = true'
Prefer:
sql = 'SELECT * '
'FROM users '
'WHERE active = true'
or a heredoc.
2. Forgetting spaces between string parts
Broken example:
sql = 'SELECT *'
'FROM users'
This becomes:
SELECT *FROM users
Fix it by adding spaces where needed:
sql = 'SELECT * '
'FROM users'
3. Confusing code newlines with string newlines
With adjacent literals:
sql = 'SELECT * '
'FROM users'
The final string is:
Comparisons
| Approach | Best for | Keeps line breaks in final string? | Readability | Notes |
|---|---|---|---|---|
+ concatenation | Simple dynamic joining | No, unless added manually | Low | Verbose for long strings |
| Adjacent string literals | Splitting one string over code lines | No | Good | Clean when you just want one long string |
| Heredoc | SQL, HTML, templates, long text | Yes | Excellent | Usually the best option for formatted text |
| Backslash continuation | Continuing an expression across lines | No | Fair | Less expressive than heredoc |
Adjacent literals vs heredoc
Cheat Sheet
Quick reference
Adjacent string literals
text = 'Hello, '
'world'
- Ruby combines them into one string
- Good for long one-line output
- Remember spaces between parts if needed
Heredoc
text = <<~TEXT
Hello
world
TEXT
- Best for multi-line content
- Preserves line breaks
<<~removes common indentation
Backslash continuation
text = 'Hello, ' \
'world'
- Continues an expression onto the next line
- Less readable than heredoc for large blocks
Interpolation rules
name = 'Ada'
text = "Hello, #{name}"
- Single quotes: no interpolation
- Double quotes: interpolation works
- Heredoc usually supports interpolation unless using a non-interpolating form
Good SQL style
sql =
FAQ
Can Ruby automatically concatenate strings on separate lines?
Yes. Adjacent string literals can be combined without +, as long as they are written as neighboring literals in a valid expression.
What is the cleanest way to write long SQL in Ruby?
Usually a heredoc, because it keeps the SQL readable and formatted like normal SQL.
Does a heredoc include newline characters?
Yes. A heredoc preserves line breaks inside the string.
If I do not want newline characters, should I still use a heredoc?
Usually no. If you want one flat string, adjacent string literals are often simpler.
Is + wrong for joining strings in Ruby?
No, but it is often less readable for long static strings.
Can I interpolate variables inside a multi-line Ruby string?
Yes, if you use double-quoted strings or an interpolating heredoc.
Are multi-line SQL strings safe?
The formatting style is safe, but interpolating untrusted values directly into SQL is not. Use parameterized queries for values.
What does <<~ mean in a heredoc?
It creates a heredoc and strips common indentation, which helps keep your Ruby code nicely indented.
Mini Project
Description
Create a small Ruby script that builds and prints readable SQL queries using both adjacent string literals and a heredoc. This project helps you see the difference between writing one flat string and writing a formatted multi-line string.
Goal
Write a Ruby script that creates two SQL queries without using + concatenation and shows how each one is output.
Requirements
- Create one query using adjacent string literals
- Create one query using a heredoc
- Print both queries to the console
- Make the SQL readable and valid as plain text
Keep learning
Related questions
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.
Difference Between require and include in Ruby
Learn the difference between require and include in Ruby, when to load a file, and when to mix module methods into a class.
Fixing Ruby Gem Native Extension Errors: mkmf.rb Can't Find Header Files for Ruby
Learn why Ruby gem installs fail with missing ruby.h, how native extensions work, and how to fix header file errors on Linux servers.