["H", "A", "L"].collect {|x| x.succ } # => ["I", "B", "M"] but
["H", "A", "L"].each {|x| x.succ } # => ["H", "A", "L"]
What is causing the difference in output here?
The succ method increments a string.
The result of the block in Array#each are completely discarded, the result of each is the array itself (that's why you get the original ["H","A","L"]). Here you want a collect/map as you show in the first snippet (which creates a new array and leaves the old one untouched).
The output of each is discarded because each is the classical imperative for-loop: you need to do some kind of side-effect (read from a file, print to screen, update an array/hash, ...) to effectively do something.
My advice is to avoid each unless there is a good reason for it. I mean, it's ok to use each to write lines to a file, for example, but never to emulate a map, select, inject, or other FP abstractions.
An alternate approach using each_char:
"HAL".each_char.map {|x| x.succ } # => ["I", "B", "M"]
or just map
["H","A","L"].map {|x| x.succ } # => ["I", "B", "M"]
Cheers :)