From: Brian Candler Date: 2008-10-31T05:56:13+09:00 Subject: Re: Problem with copying array Alan Slater wrote: > arrays (even arrays of 'primitives' like strings) don't actually > contain the objects that fill each entry, they instead (effectively) > link to those objects. Yes - they contain references to objects. > So, .delete_at and .slice! (for example) don't > remove things from the array, they delete the objects that are being > linked to completely. No - they delete the references from the array. The objects themselves are unchanged. If there are other references to them elsewhere in the system, they will live on. If the array element was the only reference to the object, so that there are no more now, then at some point in the future the object will be garbage-collected. > This explains my problem (why, whenever I delete an entry from an array, > it also deletes it from every copy of the array). No - you are deleting from a single array, but you have multiple references to that array from other places, so they all see the same changed array. A good way to probe this is with the 'object_id' method. irb(main):001:0> a = [[1,2,3],[4,5,6]] => [[1, 2, 3], [4, 5, 6]] irb(main):002:0> a.object_id => -605380508 irb(main):003:0> a[0].object_id => -605380598 irb(main):004:0> a[1].object_id => -605380608 irb(main):005:0> b = a.dup => [[1, 2, 3], [4, 5, 6]] irb(main):006:0> b.object_id => -605417698 irb(main):007:0> b[0].object_id => -605380598 irb(main):008:0> b[1].object_id => -605380608 You can see that a and b are different objects, but a[0] and b[0] point to the same object (ditto a[1] and b[1]). Diagramatically: a -----> [ . , . ] | | v v [1,2,3] [4,5,6] ^ ^ | | b -----> [ . , . ] The sub-arrays don't belong to 'a' any more than they belong to 'b'. So the consequence is: irb(main):009:0> a[0] << 99 => [1, 2, 3, 99] irb(main):010:0> a => [[1, 2, 3, 99], [4, 5, 6]] irb(main):011:0> b => [[1, 2, 3, 99], [4, 5, 6]] However if you make a modification to one of the outer arrays, e.g. by adding or removing an element, this is fine: irb(main):012:0> a << [7,8,9] => [[1, 2, 3, 99], [4, 5, 6], [7, 8, 9]] irb(main):013:0> a => [[1, 2, 3, 99], [4, 5, 6], [7, 8, 9]] irb(main):014:0> b => [[1, 2, 3, 99], [4, 5, 6]] > So, how could I simply remove an object from an array, without deleting > the object itself? slice! or delete_at Regards, Brian. -- Posted via http://www.ruby-forum.com/.