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
selfif a separator was found and removed - Returns
nilif 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