I have an array of values that I use as a reference for order when I’m printing out hash values. I’d like to modify the array so that the array values are “prettier”. I figured I’d just dup or clone the array, change the values and the original object would remain unchanaged. However (in irb)…
@arr = ['stuff', 'things']
a = @arr.clone
b = @arr.dup
So, at the very least, a and @arr are different objects:
a.object_id == @arr.object_id
=> false
But now it gets strange
a[0].capitalize!
a
=> ['Stuff', 'things']
@arr
=> ['Stuff', 'things'] ##<-what?
b
=> ['Stuff', 'things']## <-what???
ok… so modifying one changes the others, lets change it back?
a[0] = 'stuff'
a
=> ['stuff', 'things']
@arr
=> ['Stuff', 'things'] ## <- WHAT?????
For completeness b[1].capitalize! has the same effect, capitalizing all three array’s second position
So… does the bang on the end of capitalize make it extra potent? Enough to cross over to other objects?? I know of other ways of doing this, but this just seemed extremely odd to me. I assume this has something to do with being a “shallow copy”. Suggestions on the best way to do this?
dupandclonemake new instances of the arrays, but not of the content, it is no deep copy.See:
The elements inside the array share the same object_id – they are the same object. The arrays have different object ids.
When you
a[0].capitalize!you modify an object, which is part in three different arrays.See also