From what I understand, when you set an object = to another, it will always be a reference, so we have methods like .dup
and .clone
to actually create a copy of an object and not a reference.
However, I am duplicating or cloning an array of hashes and then when I delete a key from the original hash they are being deleted from the copies! This is not supposed to happen, I wonder what I'm doing wrong.
Code:
or_data = {title: 'some title', tracks: [ { name: 'track one', position: 0,
artist: 'orignal artist', composer: 'original composer', duration: '1:30' },
{ name: 'track two', position: 1, artist: 'some other guy',
composer: 'beethoven', duration: '2:10' } ] }
new_hash = or_data.dup
# or new_hash = or_data.clone, either way produces the same result
or_data[:tracks].each { |e| e.delete(:position) }
The :position
key will also be deleted from new_hash
!
This happens regardless of whether I use .dup
or .clone
.
I just read a post that says one should use:
new_hash = Marshal.load( Marshal.dump(or_data) )
This does work. But why? Because .dup
and .clone
do "shallow copies" meaning they will create a reference to :tracks
(in this example) instead of a copy because it is an array of hashes contained within a hash?