rubyguides

String#concat

str.concat(other)

The concat method joins one or more strings to the receiver, modifying it in place. It accepts a single string, multiple string arguments, or even integer arguments which are converted to their character equivalents.

This method is equivalent to the + operator but can handle multiple arguments in a single call, making it slightly more convenient for joining several strings at once.

Basic usage

The simplest form of concat joins a single string to the receiver:

str = "Hello"
str.concat(" World")
str  # => "Hello World"

"Ruby".concat(" is awesome")
# => "Ruby is awesome"

That first example shows the in-place behavior directly. The receiver changes, so the same variable now carries the longer string without needing a separate assignment.

Multiple arguments

Unlike the + operator, concat can accept multiple strings in a single call. Passing several arguments at once reduces the number of method calls and keeps the concatenation intent clear when you are joining many pieces in one step:

str = "Start"
str.concat(" ", "Middle", " ", "End")
str  # => "Start Middle End"

This can be cleaner than chaining multiple + operations. The multi-argument form is useful when you already know the pieces you want to append, since it keeps the call compact and avoids repeating the receiver for every small addition:

# Using +
"a" + "b" + "c" + "d"  # => "abcd"

# Using concat with multiple args
"a".concat("b", "c", "d")  # => "abcd"

The multi-argument form is useful when you already know the pieces you want to append. It keeps the call compact and avoids repeating the receiver for every small addition.

Integer arguments

One unique feature of concat is that it accepts integer arguments, converting each to its corresponding character using the character encoding:

str = "Hello"
str.concat(33)  # ASCII 33 = "!"
str  # => "Hello!"

# Multiple integers
"".concat(72, 101, 108, 108, 111)  # "Hello"

This works with the integer Unicode code point, so you can also use it for emoji and other Unicode characters. Because the integer form uses character codes, it is best suited to small helpers or deliberate string construction where the code point is the most direct representation you already have:

"Welcome".concat(128075)  # 👋
# => "Welcome👋"

Because the integer form uses character codes, it is best suited to tiny helpers or deliberate string construction. It is less common than regular string concatenation, but it can still be a handy shorthand when the code point is the most direct representation you already have.

The + operator alternative

The + operator is functionally equivalent to concat for single-string concatenation, but creates a new string rather than modifying in place:

# concat - modifies in place
a = "Hello"
a.concat(" World")
a  # => "Hello World"

# + - creates new string
b = "Hello"
b + " World"  # => "Hello World"
b            # => "Hello" (unchanged)

The difference matters when you want to preserve the original string for later use. concat mutates the receiver, while + gives you a fresh string that can be passed around without side effects.

Performance consideration

Since concat modifies the string in place, it avoids creating intermediate string objects. For building strings iteratively, using concat is more memory-efficient than using +:

# Less efficient - creates many intermediate strings
result = ""
%w[foo bar baz].each { |s| result += s }

# More efficient - modifies in place
result = ""
%w[foo bar baz].each { |s| result.concat(s) }

That trade-off is usually small in short scripts, but it becomes more noticeable in loops that build larger strings. In those cases, avoiding the extra temporary objects can keep the code a little lighter.

Practical example: building SQL queries

concat is handy for building queries or URLs where you need to append multiple segments:

def build_query(base_url, params)
  url = base_url.dup
  params.each do |key, value|
    url.concat(key, "=", value, "&")
  end
  url.chomp("&")  # Remove trailing &
end

build_query("https://api.example.com?", { page: "1", limit: "10" })
# => "https://api.example.com?page=1&limit=10"

The helper keeps the builder logic small while still showing exactly how the query string is assembled. Using concat here makes the mutation explicit, which can be easier to follow than a long interpolation chain.

See Also

  • split - Splits a string into an array based on a delimiter
  • replace - Replaces the entire content of a string
  • array-join - Joins array elements into a string