rubyguides

String#next

next -> new_string

#next (also known as #succ) returns the next string in ASCII sequence. It increments the last character of the string and wraps around — similar to how a counter works. It’s useful for generating sequential identifiers, ranges of labels, or stepping through alphabetical sequences.

How Successor Generation Works

The algorithm increments the rightmost character that isn’t at its maximum. If a character wraps past its maximum, it resets to the minimum and carries to the next character leftwards.

"a".next        # => "b"
"z".next        # => "aa"
"az".next       # => "ba"
"ZZ".next       # => "AAA"
"199".next      # => "200"

The key rule: characters increment within their own range. Lowercase letters go a→z→aa, uppercase go A→Z→AA, digits go 0→9→00.

Basic Usage

"hello".next    # => "hellp"
"world".next    # => "worle"

"abc".next      # => "abd"
"abz".next      # => "aca"

"file1".next    # => "file2"
"file9".next    # => "filf"

Each call returns a new string — the original is unchanged.

Multiple Successor Calls

Calling next repeatedly steps through a sequence:

s = "a"
5.times { puts s = s.next }
# a, b, c, d, e

For alphabetic sequences with a fixed width (padded with leading characters):

"a".next.next   # => "c"
"a9".next       # => "b0"
"z9".next       # => "aa0"

Interaction with Digits and Letters

The successor of "9" is "10" — a new character is added:

"9".next        # => "10"
"99".next       # => "100"

Mixed alphanumeric:

"a1".next       # => "a2"
"a9".next       # => "b0"
"z1".next       # => "z2"
"z9".next       # => "aa0"

With Padding

To maintain a fixed width (useful for sorted identifiers):

def padded_successor(str, width)
  str.next.rjust(width, str[0])
end

padded_successor("a", 3)    # => "b"
padded_successor("z", 3)    # => "aa"  (not padded)

For consistent-width sequences, use rjust after the successor:

def next_padded(str, width)
  str.next.rjust(width, '0')
end

next_padded("9", 2)    # => "10"
next_padded("99", 3)   # => "100"

Generating Ranges

Generate a range of sequential strings with #next:

first = "alpha"
last  = "alphd"
current = first
while current <= last
  puts current
  current = current.next
end
# alpha, alphb, alphc, alphd

For cases where character ranges matter:

# Generate sequential codes
def generate_codes(start, count)
  code = start
  count.times.each_with_object([]) do |_, codes|
    codes << code
    code = code.next
  end
end

generate_codes("A01", 5)
# => ["A01", "A02", "A03", "A04", "A05"]

Performance

Successor generation is fast — O(n) in the string length. For very long strings, each call touches every character from the rightmost non-maximum position to the end. Most practical uses involve short strings (3–10 characters).

succ — The Alias

#succ is an exact alias for #next. Both methods do the same thing:

"abc".next == "abc".succ  # => true

Use whichever reads more naturally in context.

Comparison with Other Methods

  • #next vs #chr: #chr converts an integer to a single character; #next steps to the next string in sequence.
  • #next vs #succ vs #advance (from Date): #next on strings is for character sequences; Date#advance moves a calendar date forward.

Edge Cases

Empty string:

"".next  # => "aa"

Only maximum characters:

"Z".next  # => "AA"
"9".next  # => "10"

Binary-like strings with consistent width:

"000".next  # => "001"
"999".next  # => "0000"

See Also