From: Stefano Crocco Date: 2006-12-08T06:01:51+09:00 Subject: Re: Array changing after concat function Alle 21:49, gioved狸 7 dicembre 2006, Drew Olson ha scritto: > WKC CCC wrote: > > I've found that using: > > > > copy = one.map { |el| el.clone } > > > > will copy all elements into the new array without referring to the same > > object. > > Is there a reason why the clone function has been ommitted from the API > > doc? > > It seems much simpler to just clone the array rather than each element > individually: > > irb(main):001:0> a=[] > => [] > irb(main):002:0> 10.times{|i| a << i} > => 10 > irb(main):003:0> a > => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] > irb(main):004:0> b = a.clone > => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] > irb(main):005:0> a[0] = 10 > => 10 > irb(main):006:0> a > => [10, 1, 2, 3, 4, 5, 6, 7, 8, 9] > irb(main):007:0> b > => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Your code doesn't solve the problem. If a contains mutable objects, such as arrays, what happens is this: irb(main):001:0> a=[[1,2],[3,4]] => [[1, 2], [3, 4]] irb(main):002:0> b=a.clone => [[1, 2], [3, 4]] irb(main):003:0> b[0].push 5 => [1, 2, 5] irb(main):004:0> a => [[1, 2, 5], [3, 4]] irb(main):005:0> What clone (and dup) produce are shallow copies, that is the object is copied, but their contents are not: a contains exactly the same objects than b does. Because of this, you can't change one of the elements of b whitout changing the element of a: the two are the same object. Instead, what your example shows is that a and b are not the same object: you can add an element to a whithout changing b. But here you're changing the arrays, not he objects they contain, which was the problem of the original poster. Stefano