Have a look at the code below:
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
p "Using .dup"
p "-----------"
p "or_data : #{or_data.object_id}"
p "new_hash : #{new_hash.object_id}"
p "or_data[:tracks] :#{or_data[:tracks].object_id}"
p "new_hash[:tracks] : #{new_hash[:tracks].object_id}"
or_data[:tracks].each { |e| e.delete(:position) }
new_hash = Marshal.load( Marshal.dump(or_data) )
p "Marshalling"
p "-----------"
p "or_data : #{or_data.object_id}"
p "new_hash : #{new_hash.object_id}"
p "or_data[:tracks] :#{or_data[:tracks].object_id}"
p "new_hash[:tracks] : #{new_hash[:tracks].object_id}"
Output:
"Using .dup"
"-----------"
"or_data : 5282580"
"new_hash : 5282568"
"or_data[:tracks] :5282592"
"new_hash[:tracks] : 5282592"
"Marshalling"
"-----------"
"or_data : 5282580"
"new_hash : 5282172"
"or_data[:tracks] :5282592"
"new_hash[:tracks] : 5282112"
The reason the position
key gets deleted when using .dup
or .clone
is because the tracks
key still refers to the same array object. Where as after Marshalling the tracks
key refers to an entire new array object.