Ruby hash.delete(:key) deleting copies and clones as well -


from understand, when set object = another, reference, have methods .dup , .clone create copy of object , not reference.

however, duplicating or cloning array of hashes , when delete key original hash being deleted copies! not supposed happen, wonder 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 same result  or_data[:tracks].each { |e| e.delete(:position) } 

the :position key deleted new_hash!

this happens regardless of whether use .dup or .clone.

i read post says 1 should use:

new_hash = marshal.load( marshal.dump(or_data) ) 

this work. why? because .dup , .clone "shallow copies" meaning create reference :tracks (in example) instead of copy because array of hashes contained within hash?

have @ 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 position key gets deleted when using .dup or .clone because tracks key still refers same array object. after marshalling tracks key refers entire new array object.


Comments