Array#dupのマニュアルを読んでいて「「浅い(shallow)」コピー」という言葉が出て来たので調べた。
Rubyで変数をコピーした時には、基本的には値を参照している。新たに値を生成している訳ではない。
これは実際にdupを行い、要素のオブジェクトIDを確認すればわかる。
a = ['japan', 'us', 'uk']
b = a.dup
# 要素のオブジェクトIDが一致する。
a[0].object_id # => 69990290634820
b[0].object_id # => 69990290634820
# 変数同士は異なるオブジェクトID。
a.object_id # => 69990290634660
b.object_id # => 69990290614460
同様のことは下記の記事に記載されている。
「深いコピー」はMarshalモジュールを使用すれば実装可能。
Marshalモジュールについて
公式のリファレンスの内容だと今いちわからなかったので、以下「パーフェクトRuby」から抜粋。
Marshalはオブジェクトを永続化するための機能を提供するモジュールです。
「永続化」という単語が引っかかったが、要は参照元の変数が無くなっても独立してデータが保持される状態にする、ということ。
下記の方法で深いコピーを行う。
b = Marshal.load(Marshal.dump(a))
# 深いコピーのため要素のオブジェクトIDは異なる。
a[0].object_id # => 69990290634820
b[0].object_id # => 69990289794560