String#chomp
str.chomp(separator) The chomp method removes the trailing record separator from a string. By default, it removes \n, \r\n, or \r depending on the platform. This is particularly useful when reading lines from files or user input, where you typically want to remove the trailing newline.
In everyday Ruby code, chomp is a small but practical cleanup step. It lets you keep the rest of the string intact, which matters when whitespace in the middle of the text is meaningful. That makes it a good fit for line-oriented input, simple parsing, and any case where you want to preserve the original content shape.
Basic Usage
When called without arguments, chomp removes any trailing newline characters:
"hello\n".chomp
# => "hello"
"hello\r\n".chomp
# => "hello"
"hello\r".chomp
# => "hello"
Those examples show the default newline handling in a compact way. In practice, this is the part of chomp most people reach for first, because it removes line endings without changing the visible text that came before them.
If there’s no trailing separator, chomp returns the string unchanged:
"hello".chomp
# => "hello"
That second example matters because chomp is a safe cleanup step, not a blanket rewrite. If the text already ends the way you want, the method leaves it alone instead of forcing a change.
Specifying a custom separator
You can pass a string argument to remove a custom trailing separator:
"hello!".chomp("!")
# => "hello"
"path/to/file/".chomp("/")
# => "path/to/file"
"data---".chomp("---")
# => "data"
When you use a custom suffix, the intent is usually to trim one known marker from the end of the string. Keeping that scope tight makes it easier to reason about later parsing steps and avoids surprising changes in the middle of the text.
Using a regex separator
A regular expression can be used to remove more complex trailing patterns:
"hello123".chomp(/\d+/)
# => "hello"
"foo.bar.baz".chomp(/\.[a-z]+/)
# => "foo.bar"
The regex form is handy when the ending pattern varies a little, but it still behaves like a suffix check rather than a search-and-replace across the whole string. That keeps the method predictable when you are cleaning structured input. It is a good fit for logs, generated files, or any line-oriented text where the ending pattern can change without the rest of the record changing.
Multiple separators
If the separator appears multiple times at the end, chomp only removes one occurrence:
"hello\n\n".chomp
# => "hello\n"
"test!!!".chomp("!!")
# => "test!"
This one-at-a-time behavior is easy to miss, especially if you are expecting it to act like gsub. If you need to remove every trailing match, call chomp repeatedly or use a different method that is meant for bulk replacement.
Practical example: processing file lines
When reading lines from a file, chomp is essential to remove the trailing newline:
File.readlines("data.txt").each do |line|
cleaned = line.chomp
puts cleaned.upcase
end
This pattern shows up often in scripts that print or compare file contents. chomp keeps the data readable while avoiding an extra blank line or a stray newline character in later processing.
It also makes later comparisons easier to read. When you are diffing, filtering, or validating text, stripping only the record separator avoids touching the actual content you care about.
Comparison with strip
While chomp only removes trailing record separators, strip removes both leading and trailing whitespace:
" hello \n".chomp
# => " hello "
" hello \n".strip
# => "hello"
"\tdata\t".chomp
# => "\tdata\t"
"\tdata\t".strip
# => "data"
Use strip when surrounding whitespace is noise, and use chomp when the line ending is the only part you want to remove. That distinction matters when the spaces at the start of a string are part of the data.
Comparison with chop
The chop method removes the last character unconditionally, while chomp only removes record separators:
"hello\n".chop
# => "hell"
"hello\n".chomp
# => "hello"
"hello!".chop
# => "hell"
"hello!".chomp("!")
# => "hello"
chop is a blunt tool, while chomp is specific about the newline-style ending it will remove. That makes chomp the safer default for line-based input, because it avoids trimming a real character by accident.
Common pitfall: mutating the original string
Remember that chomp returns a new string and does not modify the original. Use chomp! if you need in-place modification:
str = "hello\n"
str.chomp
puts str.inspect # => "hello\n"
str.chomp!
puts str.inspect # => "hello"
This distinction matters in loops and helpers where you might reuse the same variable later. If you need to keep the original untouched, stick with chomp; if you want to reuse the same object, the bang version makes that intent explicit.