2012-09-19 15 views
7

Tengo una matriz de valores que utilizo como referencia para el pedido cuando estoy imprimiendo valores hash. Me gustaría modificar la matriz para que los valores de la matriz sean "más bonitos". Pensé que duplicaría o clonaría la matriz, cambiaría los valores y el objeto original permanecería intacto. Sin embargo (en IRB) ...Tanto dup como clon devuelven diferentes objetos, pero modificarlos altera el objeto original

@arr = ['stuff', 'things'] 
a = @arr.clone 
b = @arr.dup 

Así, al menos, una y @arr son objetos diferentes:

a.object_id == @arr.object_id 
=> false 

Pero ahora se pone extraño

a[0].capitalize! 
a 
=> ['Stuff', 'things'] 
@arr 
=> ['Stuff', 'things'] ##<-what? 
b 
=> ['Stuff', 'things']## <-what??? 

ok ... así que modificar uno cambia a los demás, ¿podemos cambiarlo de nuevo?

a[0] = 'stuff' 
a 
=> ['stuff', 'things'] 
@arr 
=> ['Stuff', 'things'] ## <- WHAT????? 

Para completar b [1] .capitalize! tiene el mismo efecto, capitalizando las tres matrices en la segunda posición

Entonces ... ¿la explosión al final de capitalizar lo hace más potente? ¿Suficiente para cruzar a otros objetos? Conozco otras formas de hacerlo, pero esto me pareció extremadamente extraño. Supongo que esto tiene algo que ver con ser una "copia superficial". Sugerencias sobre la mejor manera de hacer esto?

Respuesta

8

dup y clone crean nuevas instancias de las matrices, pero no del contenido, no es una copia profunda.

Ver:

array0 = ['stuff', 'things'] 
array1 = array0.clone 
array2 = array0.dup 

puts "Array-Ids" 
p array0.object_id 
p array1.object_id 
p array2.object_id 

puts "Object ids" 
array0.each_with_index{|_,i| 
    p array0[i].object_id 
    p array1[i].object_id 
    p array2[i].object_id 
    p '--------' 
} 

Los elementos dentro de la cuota de array el mismo object_id - que son el mismo objeto. Las matrices tienen diferentes identificadores de objeto.

Cuando modifica a[0].capitalize! un objeto, que forma parte de tres matrices diferentes.

Ver también

+0

Ah ... ya veo. También veo que saber lo que necesitaba era una "copia profunda" hubiera ayudado enormemente a mi búsqueda: ¡Gracias! – jearl

Cuestiones relacionadas