Then if I'm new to the language and I'm reading someone's code, it may be harder for me to understand what's going on, unless the variables are named such as to give a hint e.g. arr_grades, hash_address.

That's true, but rubys library design is based on the idea that you should not tie down the type of a variable in the syntax, because if you do that, polymorphism becomes a lot more difficult (c.f. Java's interfaces, or C++'s multiple-inheritance).

The name of the parameter is "array", but because there is no type indication, this will work just as well with a File (print each line) a Set (print every element of the set), a Struct or some other object that happens to have an each() method that works like this. According to the idiom, an each method should "walk through" a collection - as long as you use idiomatic design, your code will remain relatively easy to interpret.

I like this strategy, but as you noted, it does have some drawbacks if you want to figure out what a complex piece of code does exactly, or when the idiom is broken.