Edited at

Ruby 参照、浅いコピー、深いコピー

More than 1 year has passed since last update.

配列に対しての参照渡し、浅いコピー、深いコピーについてのメモ。


参照渡し

=を使用して配列の複製を行う。


参照

a1 = "ruby java python".split

#参照渡し
a2 = a1
puts "a1:#{a1}"
puts "a2:#{a2}"
#配列オブジェクトが同じか確認
p a1.equal?(a2)
p a1.object_id
p a2.object_id
p a1[0].equal?(a2[0])
p a1[0].object_id
p a2[0].object_id
#配列に対して変更
a1.sort!
#配列内容の確認
puts "a1:#{a1}"
puts "a2:#{a2}"
#要素の値に対して変更
a1[0].capitalize!
#配列内容の確認
puts "a1:#{a1}"
puts "a2:#{a2}"


実行結果

a1:["ruby", "java", "python"]

a2:["ruby", "java", "python"]
true
70328621736780
70328621736780
true
70328621736740
70328621736740
a1:["java", "python", "ruby"]
a2:["java", "python", "ruby"]
a1:["Java", "python", "ruby"]
a2:["Java", "python", "ruby"]

配列もその中の要素も元のa1と変わらないことがわかる。

配列に対してsortを実行するとa2にも影響を受け

a1の要素0に対してcapitalizeを実行するとa2にも影響している。

refBf.jpg

↓↓↓ 処理実行後 ↓↓↓

refAf.jpg


浅いコピー

dupを使用して配列の複製を行う。


浅いコピー

a1 = "ruby java python".split

#浅いコピー
a2 = a1.dup
puts "a1:#{a1}"
puts "a2:#{a2}"
#配列オブジェクトが同じか確認
p a1.equal?(a2)
p a1.object_id
p a2.object_id
p a1[0].equal?(a2[0])
p a1[0].object_id
p a2[0].object_id
#配列に対して変更
a1.sort!
#配列内容の確認
puts "a1:#{a1}"
puts "a2:#{a2}"
#要素の値に対して変更
a1[0].capitalize!
#配列内容の確認
puts "a1:#{a1}"
puts "a2:#{a2}"


実行結果

a1:["ruby", "java", "python"]

a2:["ruby", "java", "python"]
false
70363447026880
70363447026740
true
70363447026860
70363447026860
a1:["java", "python", "ruby"]
a2:["ruby", "java", "python"]
a1:["Java", "python", "ruby"]
a2:["ruby", "Java", "python"]

配列のオブジェクトが違うことがわかる。

そのためソートを実行するとa2には影響がない。

ただし要素の値に関しては同一のものを参照しているため

capitalizeを実行するとa2も値が変更されている。

shallowCopyBf.jpg

↓↓↓ 処理実行後 ↓↓↓

shallowCopyAf.jpg


深いコピー

Marshalを使用して配列の複製を行う。


深いコピー

a1 = "ruby java python".split

#深いコピー
a2 = Marshal.load(Marshal.dump(a1))
puts "a1:#{a1}"
puts "a2:#{a2}"
#配列オブジェクトが同じか確認
p a1.equal?(a2)
p a1.object_id
p a2.object_id
p a1[0].equal?(a2[0])
p a1[0].object_id
p a2[0].object_id
#配列に対して変更
a1.sort!
#配列内容の確認
puts "a1:#{a1}"
puts "a2:#{a2}"
#要素の値に対して変更
a1[0].capitalize!
#配列内容の確認
puts "a1:#{a1}"
puts "a2:#{a2}"


実行結果

a1:["ruby", "java", "python"]

a2:["ruby", "java", "python"]
false
70194731237460
70194731242700
false
70194731241740
70194731242800
a1:["java", "python", "ruby"]
a2:["ruby", "java", "python"]
a1:["Java", "python", "ruby"]
a2:["ruby", "java", "python"]

配列とその要素いずれも同一でないことがわかる。

よってsortcapitalizeのどちらの実行もa2に影響がない。

deepCopyBf.jpg

↓↓↓ 処理実行後 ↓↓↓

deepCopyAf.jpg