2012-09-19 12 views
7

ハッシュ値を出力する際に​​参照用に使用する値の配列があります。私は配列の値が "よりきれい"になるように配列を変更したいと思います。私は配列をdupまたはクローンして値を変更するだけで、オリジナルのオブジェクトは処理されないままであると考えました。しかし、(IRBに)...dupとクローンの両方が別のオブジェクトを返しますが、それらを変更すると元のオブジェクトが変更されます

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

だから、非常に少なくとも、Aと@arrは異なるオブジェクトです:

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

しかし、今では奇妙な

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

[OK]を取得します... 1つを変更すると、他のものが変更され、それを元に戻すことができますか?

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

完全性のためにb [1] .capitalize! 3つの配列のすべての2番目の位置を大文字にして同じ効果を持ちます

大文字小文字の末尾には強烈な印象がありますか?他のオブジェクトと交差するには十分ですか?私はこれを行う他の方法を知っているが、これはちょうど私にとって非常に奇妙に思えた。私はこれが「浅いコピー」であることと関係があると考えています。これを行う最善の方法に関する提案?

答えて

8

dupおよびcloneは、配列の新しいインスタンスを作成しますが、内容は作成しません。ディープコピーはありません。

参照:

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 '--------' 
} 

配列を共有内の要素と同じOBJECT_ID - 彼らは同じオブジェクトです。配列には異なるオブジェクトIDがあります。

a[0].capitalize!とすると、3つの異なる配列に属するオブジェクトが変更されます。

は、ああ...私が参照してください。

+0

も参照してください。私はまた、私が必要としていたことを知っていることが、 "深いコピー"が私の検索を大いに助けてくれたことを知っているのを見ています。 – jearl

関連する問題