String#chop!
str.chop! -> str or nil The chop! method removes the last character from a string, modifying it in place. This destructive operation is useful when you need to clean up trailing characters from user input, file content, or any string data that might have unwanted terminators.
It is a very direct tool: one call removes one trailing character, no matter what that character is. That makes it useful when you know the extra character is always at the end and you do not need the more specific newline handling that chomp! provides.
How it works
When you call chop! on a string, it removes the final character and returns the modified string. If the text is empty, chop! returns nil instead of an empty string. Unlike chomp! which removes record separators (typically newlines), chop! removes absolutely any last character regardless of what it is.
This method is particularly useful in scenarios where you’re processing input that might have inconsistent trailing characters, or when you need to strip exactly one character from the end of a string without caring what that character is.
Practical examples
The examples below show the most common patterns for chop!. Each one demonstrates the method removing a single trailing character in place, which is the core behavior you should expect regardless of the input type.
Basic usage
# Remove the last character from a string
text = "hello"
text.chop! # => "hell"
puts text # => "hell" (modified in place)
# Works with any characters
"ruby!".chop! # => "ruby"
"12345".chop! # => "1234"
"a\nb".chop! # => "a\n" (removes 'b', not the newline)
Handling empty strings
An empty string produces nil because there is nothing to remove. That return value is important in conditional code where nil is falsy, because it lets you write a guard like if str.chop! that only runs when the string actually changed:
# Empty strings return nil
"".chop! # => nil
"a".chop! # => "" (not nil, because it has one char)
Processing file lines
A common use for chop! is cleaning up lines that were read from a file. Each line usually ends with a newline character, and removing it with chop! is faster than a more general-purpose method when you know exactly one character needs to go:
# When reading lines, each line typically ends with a newline
lines = ["first line\n", "second line\n", "third line\n"]
lines.each { |line| line.chop! }
# => ["first line", "second line", "third line"]
# This is useful for cleaning up CSV data
csv_row = "John,Doe,30\n"
csv_row.chop!
puts csv_row.split(",") # => ["John", "Doe", "30"]
User input processing
When you are handling text that came from a form or a terminal, trailing whitespace and control characters are common. A loop with chop! and end_with? gives you precise control over which characters get removed and how many passes the cleanup takes:
# Clean up user input that might have unexpected characters
def normalize_input(input)
input.chop! while input.end_with?(" ", "\t", "\n")
input
end
normalize_input("username ") # => "username"
normalize_input("email\t\n") # => "email"
In a cleanup loop like this, chop! is doing the same job repeatedly until the ending no longer matches the rule you care about. The approach stays simple because each pass only removes a single trailing character.
Important notes
The chop! method modifies the original string. If you need a non-destructive version that returns a new string, use chop (without the bang). Also be aware that chop treats the string as a sequence of characters and removes exactly one character from the end, unlike chomp which removes record separators.
# Non-destructive alternative
original = "hello"
modified = original.chop
puts original # => "hello" (unchanged)
puts modified # => "hell"
This method has been part of Ruby’s String class since early versions and remains a fundamental tool for string manipulation tasks.
If you only need to trim one final character and you do not care what that character is, chop! is the shortest path. If you need to respect a record separator or preserve more of the original string, a different method is usually a better fit.