The best I can do is relate what I think it is. I know its not the exact definition but I think you will understand .each a little better. There are classes in Ruby, almost always collections, that have some form of iteration built into them. The .each method is a way to iterate through the elements in these collections.
Example:
parts = ['toast', 'is', 'amazing']
parts.each do |part|
p part
end
The word between the "pipes"(||) is used as a representative of the current element in the iteration. First run part will be toast, then is, then amazing. However changes made to the representative are not always reflected in the collection. Not always is indefinite isn't it? When do the changes take effect. It all depends on how good a shallow copy gets you. With simpler items you can easily make a duplicate but with larger more complex items copying becomes more difficult.
Example:
# When shallow copy works.
parts = ['toast', 'is', 'amazing']
parts.each do |part|
part += 'er'
end
p parts # Prints ['toast', 'is', 'amazing']
# When shallow copy fails.
parts = [Sprite.new, Sprite.new, Sprite.new]
parts.each do |part|
part.x += 50
end
p parts[0].x, parts[1].x, parts[2].x # 50 50 50
Just keep that in mind when using .each. If you do want to manipulate an array's innards but are unsure on the copy situation you can either "for i in 0...array.size" or specifically for Array objects use .each_index do |i|
Example:
parts = ['toast', 'is', 'amazing']
parts.each_index do |i|
parts[i] += 'er'
end
p parts # Prints ['toaster', 'iser', 'amazinger']
For hashes you have a couple approaches. First a little quickie for Hashes. Hashes use {} instead of [] for Arrays. Hashes use a key to reference a piece of data stored within it. Like the index for an Array. But with a Hash that key could be anything. An Integer, String, or even a Window. Its really up to you how you want to attack your data storage problem.
To iterate through a hash with .each you need to define between the pipes two values. One for the key and one for the data referenced by the key.
Example:
parts = { 0 => 'toast', 1 => 'is', 2 => 'amazing' }
parts.each do |key, value|
p key, value
end
p parts # Prints 0 toast, 1 is, 2 amazing
That was a little deceptive. When key value pairs are entered into Hashes, regardless of the order you put them into the hash, it does not guarantee that the data will stay in that order. The last item you throw in a Hash could be the first item encountered when iterating. Point is iterating through hashes is guess work.
Like I said above you can iterate through Hashes a bunch a different ways. each, each_pair, each_key, each_value. each_pair is the synonym for each. It works the same way as each it just takes twice as much time to type... Sometimes when dealing with hashes you might only care about the key and not the value. For this we use .each_key
parts = { 0 => 'toast', 1 => 'is', 2 => 'amazing' }
parts.each_key do |key|
p key
end
p parts # Prints 0, 1, 2
Likewise there is a method for just the values of a hash.
parts = { 0 => 'toast', 1 => 'is', 2 => 'amazing' }
parts.each_value do |value|
p value
end
p parts # Prints 'toast', 'is', 'amazing'
As always, good luck with it Gando! :thumb: