rubyguides

String#chomp!

string.chomp! -> self or nil
string.chomp!(separator) -> self or nil

The chomp! method is the mutating, in-place version of chomp. It belongs to Ruby’s String class and is commonly used to remove trailing record separators, typically newlines, from text that you want to keep processing in the same object.

That makes chomp! useful when you are reading many lines or normalizing user input and want to avoid allocating a fresh object for each trim.

Syntax

string.chomp!       # Uses the default record separator ($/)
string.chomp!(separator)  # Uses the specified separator

Parameters

  • separator (optional) — A string to use as the record separator. Defaults to $/ (usually "\n").

How it works

chomp! removes the record separator from the end of the string only if it exists. The key characteristic of bang methods (methods ending with !) is that they modify the object in place rather than returning a new string.

The bang convention

In Ruby, bang methods (suffix !) conventionally indicate mutation. Unlike their non-bang counterparts, bang methods modify the receiver directly:

  • chomp — Returns a new string (non-mutating)
  • chomp! — Modifies the string in place (mutating)

Return Value

  • Returns self if a separator was found and removed
  • Returns nil if no separator was present at the end

This nil return is a common signal that no modification occurred. It is helpful in control flow, because you can branch only when a trim actually happened.

Examples

Each example below focuses on a different part of the API. First we remove a standard newline, then we look at custom separators, and finally we show how the return value can help you decide whether anything changed.

Example 1: Removing a trailing newline

greeting = "Hello, World!\n"
greeting.chomp!

puts greeting.inspect  # => "Hello, World!"

The next example shows that chomp! removes at most one separator from the end of the receiver. That detail matters when you are working with line-oriented input, because repeated separators are preserved except for the final one, not collapsed all at once.

Example 2: Handling multiple separators

# Multiple newlines are NOT removed - only ONE separator
text = "line1\n\n\n"
text.chomp!
puts text.inspect  # => "line1\n\n"

# Using a custom separator
data = "record1|record2|record3|"
data.chomp!("|")
puts data.inspect  # => "record1|record2|record3"

The nil return value is most useful when you want to know whether the string changed. That lets you keep logging or follow-up work close to the trim itself instead of adding a separate comparison or extra conditional flag.

Example 3: Checking for nil return

# When no separator exists, chomp! returns nil
message = "No newline here"
result = message.chomp!

puts result.nil?  # => true
puts message      # => "No newline here" (unchanged)

# Common pattern: conditional processing
if message.chomp!
  puts "Newline removed"
else
  puts "No newline to remove"
end

Comparison: chomp vs chomp!

The comparison below shows the clearest way to decide between the two methods. Use the non-bang version when you need a separate copy, and use chomp! when the original string should be updated in place for later code that still needs it.

# chomp - creates a new string
original = "text\n"
copy = original.chomp

original  # => "text\n" (unchanged)
copy      # => "text"    (new string)

# chomp! - modifies in place
original = "text\n"
original.chomp!

original  # => "text"    (modified!)

The comparison above is the quickest way to remember the difference. Use chomp when you need a copy, and use chomp! when you want the original string updated in place.

Common use cases

  • Reading file lines — Removing newlines after gets
  • Processing user input — Cleaning trailing whitespace
  • String parsing — Stripping record delimiters

See Also