Question

Split Long String Literals Across Lines in Ruby Without Newlines

rubyruby-on-rails

Question

In a Ruby on Rails project that follows an 80-character line limit, how can a long string be written across multiple source-code lines without inserting newline characters into the resulting string?

For example, this message may be too long for one line:

"User X wanted to send you a message about Thing Y"

Heredocs, %Q{}, and explicit concatenation can span lines, but multiline forms may include newline characters that then need to be removed. Is there Ruby syntax that produces exactly the same value as a single-line string literal, without requiring newline stripping or unnecessary runtime work?

Backslash line continuation is also less desirable when it makes indentation difficult to read, such as:

if foo
  string = "this is a \
string that spans lines"
end

Short Answer

Ruby can join adjacent string literals automatically. Put separate quoted literals next to one another, including on indented lines, and Ruby creates one string without inserting spaces or newline characters. This is a clean way to wrap static text while keeping source lines short.

Concept

A newline in your source code is not necessarily a newline in a Ruby string value.

Ruby allows two or more string literals placed next to each other to be treated as one combined literal:

message = "User X wanted to send you "
          "a message about Thing Y"

The value is:

"User X wanted to send you a message about Thing Y"

There is no \n between you and a. The indentation before the second literal is only formatting for people reading the code.

This differs from a multiline quoted string or a heredoc, where pressing Enter is usually part of the string content. Adjacent literals are especially useful for static UI text, error messages, URLs, and SQL fragments that need to obey a line-length rule.

For literal-only strings, Ruby handles this as part of parsing the source rather than as a repeated runtime String#+ operation. In ordinary application code, the main reason to choose this style is clarity; performance should only be measured when it is genuinely important.

Mental Model

Think of adjacent string literals as pieces of a sentence printed on separate cards. Ruby reads the cards in order and places them edge to edge:

"Hello, " "Ruby!"

The cards are separate in the source file so they are easy to arrange, but their text becomes one message:

Hello, Ruby!

A heredoc is more like writing directly on a multi-line note: the line breaks on the note are normally preserved. Adjacent literals are separate cards, so the layout of the cards does not become part of the message.

Take Quiz

Syntax and Examples

Use quoted string literals directly beside each other. You may separate them with spaces, a newline, and indentation.

message = "User X wanted to send you "
          "a message about Thing Y"

puts message
# User X wanted to send you a message about Thing Y

The space after you is intentional. Ruby does not add a space automatically.

label = "Account settings"
        " are unavailable"

puts label
# Account settings are unavailable

You can use this inside an expression as well:

if foo
  string = "This is a "
           "readable string that spans source lines."
end

When interpolation is needed, keep it in the relevant piece:

user_name = "Ava"
message = "Hello, #{user_name}. "
          "Your report is ready."

# "Hello, Ava. Your report is ready."

Use double quotes when a piece needs interpolation or escape sequences. Single quotes are suitable for plain literal text:

path = 'app/'
       'services/'
       'report_builder.rb'
# "app/services/report_builder.rb"

Step by Step Execution

Consider this code:

name = "Mina"
message = "Hello, #{name}. "
          "You have a new notification."
  1. Ruby assigns "Mina" to name.
  2. Ruby reads the first part of message: "Hello, #{name}. ".
  3. #{name} is interpolated, producing "Hello, Mina. ".
  4. Ruby reads the immediately adjacent second literal: "You have a new notification.".
  5. Ruby joins the literal parts with no automatic separator.
  6. message has this value:
"Hello, Mina. You have a new notification."

The newline after the first closing quote and the leading spaces before the next quote are source formatting only. They are not included in message.

Real World Use Cases

  • Flash messages: Keep long Rails notices readable.

    flash[:notice] = "Your password has been changed. "
                     "Sign in again on your other devices."
    
  • Validation errors: Write descriptive errors without a very wide source line.

    error = "The selected plan cannot be used because "
            "your organization has reached its member limit."
    
  • API documentation or request descriptions: Build static headers and descriptions that remain easy to review.

  • URLs and file paths: Split fixed segments where it improves readability.

    docs_url = "https://docs.example.com/"
               "guides/account-security"
    
  • SQL fragments: Format a fixed query carefully, while still using parameter binding for dynamic values.

    query = "SELECT id, email FROM users "
            "WHERE active = true ORDER BY email"
    
Take Quiz

Real Codebase Usage

In production Ruby code, adjacent literals are most useful when the text is fixed and wrapping at a meaningful boundary makes it easier to scan.

Keep word boundaries explicit

Put a space in one of the pieces when words must be separated:

message = "Your export is complete. "
          "Download it from the reports page."

Combine with guard clauses

Long error messages often appear in validation or early-return paths:

def deliver_report(user)
  return false unless user.verified?

  notifier.send(
    "Your requested report is ready. "
    "It will remain available for seven days."
  )
end

Prefer parameters for changing data

Do not assemble SQL by interpolating untrusted values. Adjacent literals improve formatting, but they do not provide security:

User.where(
  "status = ? AND created_at >= ? "
  "AND created_at < ?",
  "active",
  start_time,
  end_time
)

Use a heredoc when line breaks are meaningful

For an email body, Markdown, or multi-line SQL intended to contain line breaks, a heredoc expresses that intent more clearly than adjacent literals.

Common Mistakes

Forgetting the space between words

Ruby does not insert one for you.

# Incorrect result: "Hello,world!"
greeting = "Hello," 
           "world!"

Add a space inside either literal:

greeting = "Hello, "
           "world!"

Expecting indentation to appear in the value

text = "first "
       "second"

# "first second", not "first        second"

Leading spaces outside the quotes are source indentation, not string content.

Using a multiline quoted string accidentally

This includes a newline in the result:

text = "first line
second line"

# "first line\nsecond line"

Use adjacent literals if the output must not contain a newline:

text = "first line "
       "second line"

Using + when literals are enough

This works, but is noisier for fixed text:

text = "first part " +
       "second part"

For literal pieces, omit +:

text = "first part "
       "second part"

Use + only when joining values that are computed at runtime.

Removing newlines after creating them

Calling gsub, chomp, or strip to compensate for a formatting choice can obscure the desired value. Prefer a representation that creates the correct value directly. If text is intentionally multiline, preserve it rather than stripping it accidentally.

Comparisons

TechniqueDoes it add a newline?Best use
Adjacent literals: "a" "b"NoWrapping fixed text with no line break
Explicit concatenation: "a" + "b"NoJoining dynamic values, though unnecessary for adjacent literals
Interpolation: "Hello, #{name}"No by itselfInserting a value into text
Backslash continuationNoRarely useful; can make indentation harder to read
Regular heredoc: <<~TEXTUsually yesText where line breaks are meaningful
Multiline quoted stringYesText where an embedded newline is desired

A squiggly heredoc (<<~TEXT) removes common indentation, but it does not generally remove intentional line breaks between lines. It solves an indentation problem, not the same no-newline requirement as adjacent literals.

Take Quiz

Cheat Sheet

# Wrap a static string with no newline added
text = "First part "
       "second part"

# Equivalent value
text = "First part second part"

# Interpolation in one piece
text = "Hello, #{name}. "
       "Welcome back."

# Source indentation is ignored
if enabled
  text = "One "
         "two"
end
  • Adjacent quoted literals are joined automatically.
  • Ruby adds no spaces or newlines between them.
  • Include spaces and punctuation inside the literals deliberately.
  • Prefer this for static text split solely for source readability.
  • Use a heredoc when the resulting string should contain line breaks.
  • Use parameter binding rather than interpolation for untrusted SQL values.

FAQ

Does Ruby add a space between adjacent string literals?

No. Ruby joins them exactly, so add a space inside one literal when needed.

Can I split a Ruby string across lines without using +?

Yes. Place adjacent string literals on separate lines:

text = "one "
       "two"

Does indentation before the second string become part of the string?

No. Only characters inside quotes are part of the string.

Is adjacent string literal concatenation faster than using +?

For fixed literals, Ruby can handle adjacent literals as part of parsing rather than performing the same kind of runtime concatenation as String#+. Choose this form primarily because it clearly represents static text; benchmark real hot paths if performance matters.

Should I use a heredoc for a long one-line message?

Usually no. A heredoc is better when line breaks are intended in the output. Adjacent literals are clearer when the output must be one line.

Can adjacent literals contain interpolation?

Yes. Use double-quoted literals for pieces that need interpolation:

"Hello, #{name}. " "Welcome!"

Does a squiggly heredoc remove all newlines?

No. <<~ removes common leading indentation. Newlines separating heredoc lines remain part of the text unless you explicitly handle them.

Take Quiz

Mini Project

Description

Create a small Ruby notification formatter for a Rails-style application. It produces a readable, single-line account message while the Ruby source remains within a reasonable line length. The project demonstrates adjacent string literals and interpolation without introducing unwanted newline characters.

Goal

Build a method that returns a one-line notification message for a user and plan name.

Requirements

Create a subscription_message method that accepts a user name and plan name. Return a message that includes both values. Wrap the static message across multiple Ruby source lines. Ensure the returned string contains no newline characters. Include a short example that prints the result.

Take Quiz

Keep learning

Related questions

View more