“changing” object using iterator “each”
All of you know the “each” iterator. It goes over the array or another collection, sends it of an element to block, does some stuff with it, but the original collection remains unchanged. Simple? Actually, it’s a bit more complicated. Today I wrote one method and I totally didn’t realize that I was expecting “each” iterator to change the object I invoked method on. Actually, I was really surprised when I discovered that my mistake was really working! How is it possible? Let’s look at the example:
cars = {:mercedes => {:body => "sedan", :gearbox => "automatic"},
:audi => {:body => "hatchback", :gearbox => "manual"}}
What I want to do now is to set all the cars’ parameters values to “sedan” and “manual”.
cars.each do |name, attributes|
attributes = {:body => "sedan", :gearbox => "manual"}
end
As you probably expect, it doesn’t really do what I want.
=> {:mercedes=>{:gearbox=>"automatic", :body=>"sedan"},
:audi=>{:gearbox=>"manual", :body=>"hatchback"}}
But look at this code:
cars.each do |name, attributes|
attributes[:gearbox] = "manual"
attributes[:body] = "sedan"
end
And its result:
=> {:mercedes=>{:gearbox=>"manual", :body=>"sedan"},
:audi=>{:gearbox=>"manual", :body=>"sedan"}}
How is it possible?
Actually, I didn’t change the collection of cars. It’s the same object as it was. It contains 2 cars, which are hashes and they are the same objects as they were before. That’s the difference between the second and the first example, in the first one I created a new object, and that’s what I can’t do, while in the second example I only changed the internal structure of the car, but the car itself remained the same object.