Rubyの浅いコピーと深いコピー

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

同様のことは下記の記事に記載されている。

Rubyの変数の振る舞いまとめ

「深いコピー」はMarshalモジュールを使用すれば実装可能。

Marshalモジュールについて

公式のリファレンスの内容だと今いちわからなかったので、以下「パーフェクトRuby」から抜粋。

Marshalはオブジェクトを永続化するための機能を提供するモジュールです。

「永続化」という単語が引っかかったが、要は参照元の変数が無くなっても独立してデータが保持される状態にする、ということ。
下記の方法で深いコピーを行う。

b = Marshal.load(Marshal.dump(a))

# 深いコピーのため要素のオブジェクトIDは異なる。
a[0].object_id      # => 69990290634820
b[0].object_id      # => 69990289794560
カテゴリーRuby

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

19 − sixteen =

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください