String#succ
Signature
str.succ -> new_string
str.succ! -> self
str.next -> new_string
str.next! -> self
#succ returns a new string. #succ! mutates self in place. #next and #next! are aliases that call the identical C implementation.
Numeric Increment
Digits increment with carry propagation. When 9 rolls over, it increments the digit to its left. If all digits carry, a new digit is prepended.
'0'.succ # => "1"
'8'.succ # => "9"
'9'.succ # => "10"
'00'.succ # => "01"
'09'.succ # => "10"
'99'.succ # => "100"
'1999zzz'.succ # => "2000aaa"
'0099'.succ # => "0100"
Lowercase Letters
Lowercase letters follow the same carry logic, preserving case.
'a'.succ # => "b"
'x'.succ # => "y"
'z'.succ # => "aa"
'aa'.succ # => "ab"
'az'.succ # => "ba"
'zz'.succ # => "aaa"
'z' rolls over to 'aa', not to an uppercase letter.
Uppercase Letters
Same behavior as lowercase, but preserves uppercase.
'A'.succ # => "B"
'Z'.succ # => "AA"
'AA'.succ # => "AB"
'AZ'.succ # => "BA"
'ZZ'.succ # => "AAA"
Non-Alphanumeric Characters
Non-alphanumerics use the underlying character set’s collating sequence. For ASCII/BINARY encodings, this is byte value order. Non-alphanumerics do not trigger carry propagation — only the rightmost character is ever incremented.
'***'.succ # => "**+"
'<<koala>>'.succ # => "<<koalb>>"
* (ASCII 42) increments to + (ASCII 43).
Multibyte Characters
With multibyte encodings like UTF-8, each character is treated as a codepoint. The increment follows the encoding’s collating sequence.
'å'.succ # => "å" (no next codepoint, wraps to same — depends on encoding)
Behavior varies by Ruby version and encoding. For encodings with no defined successor (or where the last codepoint rolls over), the result may be the same character or require explicit handling.
Mixed Alphanumeric Strings
Carry propagates across and between types. Letters roll over independently of digits.
'THX1138'.succ # => "THX1139"
'zz99zz99'.succ # => "aaa00aa00"
'99zz99zz'.succ # => "100aa00aa"
'ZZZ9999'.succ # => "AAAA0000"
'ZZZ9999'.succ produces 'AAAA0000' — every character type rolls over independently.
Empty Strings
Returns a new empty string.
''.succ # => ""
Binary Strings
Each byte is treated as an independent numeric value. A full-byte carry prepends \x01.
"\x00\x00\x00".succ # => "\x00\x00\x01"
"\xFF\xFF\xFF".succ # => "\x01\x00\x00\x00" (ASCII-8BIT encoding)
Frozen Strings
#succ returns a new string and is safe to use on frozen strings. #succ! raises FrozenError on frozen strings in Ruby 3.0+.
s = 'hello'.freeze
s.succ # => "hellp" # safe, returns new string
s.succ! # => FrozenError (Ruby 3.0+)
Gotchas
No numeric awareness. Successor is purely character-based.
'1.0'.succ # => "1.1", not "2.0"
Mixed-type carry cascades can surprise you. 'ZZZ9999'.succ produces 'AAAA0000' — every character type rolls over independently.
#next conflicts with the next keyword. Inside blocks using next for flow control, prefer #succ to avoid ambiguity.
Non-ASCII encodings follow the encoding’s collating sequence, which may not match locale expectations.
#pred does not exist for strings. Ruby has Integer#pred but not String#pred. There is no built-in way to get the lexicographic predecessor of a string.
See Also
String#hex— converts a hex string to an integerString#oct— converts an octal string to an integer