Вы можете использовать String # chars (1), поэтому Enumerable # chunk_ while (2), затем Enumerable # flat_map (3) в желаемый формати наконец Array # join :
str = "aaabbcaa"
str.chars.chunk_while { |x, y| x == y }.flat_map { |e| [(e.size unless e.size == 1), e.first] }.join
#=> "3a2bc2a"
Шаг за шагом
# (1)
str.chars#.to_a
#=> ["a", "a", "a", "b", "b", "c", "a", "a"]
, поэтому
# (2)
str.chars.chunk_while { |x, y| x == y }#.to_a
#=> [["a", "a", "a"], ["b", "b"], ["c"], ["a", "a"]]
затем
# (3)
str.chars.chunk_while { |x, y| x == y }.flat_map { |e| [(e.size unless e.size == 1),e.first] }
#=> [3, "a", 2, "b", nil, "c", 2, "a"]