どぼじょのIT学習ブログ

高専卒土木女子がIT業界を目指してお勉強。

Rubyの配列コピーの種類

Rubyの配列コピーについて試したので記録です🙌

目次

1. 配列のコピーの種類

配列をコピーすると同じ要素を参照するのか?他方の要素の変更の影響を受けるのか?というのが曖昧だったので、動作を試してみました!
オブジェクトIDはそのままだと桁が大きく読みづらいので、10000で割った余りの数で比較しています。
結果的には以下のような違いがあるみたいでした⛱

コピーの種類 配列のID 要素のID 要素の変更の影響
浅いコピー 異なる 同じ 受けない
深いコピー 異なる 異なる 受けない
代入 ( a = b ) 同じ 同じ 受ける

2.浅いコピー

2-1. コード

org = ["あいうえお", "abcde", "12345"]
puts "org = #{org} (元の配列)"
puts "配列 org ID:#{org.object_id % 10000}"
puts "要素 org[0] ID:#{org[0].object_id % 10000}"

# shallow copy
shal = org.dup
puts "shal = #{shal} (浅いコピー)"
puts "配列 shal ID:#{shal.object_id % 10000}"
puts "要素 shal[0] ID:#{shal[0].object_id % 10000}"

org[0] = "アイウエオ"
puts "org[0]の値を \"#{org[0]}\" に変更"
shal[1] = "ABCDE"
puts "shal[1]の値を \"#{shal[1]}\" に変更"

puts "org = #{org}"
puts "shal = #{shal}"
puts "配列 org ID:#{org.object_id % 10000}"
puts "配列 shal ID:#{shal.object_id % 10000}"
puts "要素 org[0] ID:#{org[0].object_id % 10000}"
puts "要素 shal[0] ID:#{shal[0].object_id % 10000}"
puts "要素 org[1] ID:#{org[1].object_id % 10000}"
puts "要素 shal[1] ID:#{shal[1].object_id % 10000}"
puts "要素 org[2] ID:#{org[2].object_id % 10000}"
puts "要素 shal[2] ID:#{shal[2].object_id % 10000}"

2-2. 結果

f:id:mistyrinth:20190304173243p:plain

3.深いコピー

3-1. コード

org = ["あいうえお", "abcde", "12345"]
puts "org = #{org} (元の配列)"

# deep copy
deep = Marshal.load(Marshal.dump(org))
puts "deep = #{deep} (深いコピー)"

puts "配列 org ID:#{org.object_id % 10000}"
puts "配列 deep ID:#{deep.object_id % 10000}"
puts "要素 org[0] ID:#{org[0].object_id % 10000}"
puts "要素 deep[0] ID:#{deep[0].object_id % 10000}"
puts "要素 org[1] ID:#{org[1].object_id % 10000}"
puts "要素 deep[1] ID:#{deep[1].object_id % 10000}"
puts "要素 org[2] ID:#{org[2].object_id % 10000}"
puts "要素 deep[2] ID:#{deep[2].object_id % 10000}"

3-2. 結果

f:id:mistyrinth:20190304173330p:plain

4.代入

4-1. コード

org = ["あいうえお", "abcde", "12345"]
puts "org = #{org} (元の配列)"

# substitution
sub = org
puts "sub = #{sub} (代入)"

puts "配列 org ID:#{org.object_id % 10000}"
puts "配列 sub ID:#{sub.object_id % 10000}"

org[0] = "アイウエオ"
puts "org[0]の値を \"#{org[0]}\" に変更"
sub[1] = "ABCDE"
puts "sub[1]の値を \"#{sub[1]}\" に変更"

puts "org = #{org}"
puts "sub = #{sub}"
puts "配列 org ID:#{org.object_id % 10000}"
puts "配列 sub ID:#{sub.object_id % 10000}"
puts "要素 org[0] ID:#{org[0].object_id % 10000}"
puts "要素 sub[0] ID:#{sub[0].object_id % 10000}"
puts "要素 org[1] ID:#{org[1].object_id % 10000}"
puts "要素 sub[1] ID:#{sub[1].object_id % 10000}"
puts "要素 org[2] ID:#{org[2].object_id % 10000}"
puts "要素 sub[2] ID:#{sub[2].object_id % 10000}"

4-2. 結果

f:id:mistyrinth:20190304173418p:plain