I expected that Array.each and Array.collect would never change an object, like in this example:
a = [1, 2, 3]
a.each { |x| x = 5 }
a #output => [1, 2, 3]
But this doesn't seem to be the case when you are working with an array of arrays or an array of hashes:
a = [[1, 2, 3], [10, 20], ["a"]]
a.each { |x| x[0]=5 }
a #output => [[5, 2, 3], [5, 20], [5]]
Is this behaviour expected or am I doing something wrong?
Doesn't this make ruby behaviour a little unexpected? For example, in C++ if a function argument is declared const, one can be confident the function won't mess with it (ok, it can be mutable, but you got the point).
a = [[1]],b = a.dup # => [[1]],b[0][0] = 2 #=> [[2]],a #=> [[2]].dupmakes a "shallow" copy ofa, whereas you were expecting a "deep" copy. Many sources explain this distinction in greater detail and explain ways of making a "deep" copy. This is one.#eachpasses the value to the block using deep copy.