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