Если Ruby 2,3 ... 2,7, это будет работать:
CHAR_CLASSES = {
lcase: ?a..?z,
ucase: ?A..?Z,
digit: ?0..?9,
}
p "asg3456 ERTYaeth".each_char.with_object(Hash.new(0)) { |c, o|
o[CHAR_CLASSES.find { |label, group| group === c }&.first || :other] += 1
}
Для <2,3, </p>
p "asg3456 ERTYaeth".each_char.with_object(Hash.new(0)) { |c, o|
p = CHAR_CLASSES.find { |label, group| group === c }
o[p ? p.first : :other] += 1
}