これは、C++で言う参照コピーであり、Cで言うポインタ渡しと同じ挙動です。
◆exp. shallow copy
a = [0,1,2]
b = a
b[1] = 3
p "a = " + a.to_s
p "b = " + b.to_s
実行結果は、
"a = 032"
"b = 032"
となります。『"a = 012"』で無い所に注意が必要。 shallow copyなのでbを変更すると
コピー元のaも変更されます。 では、bを変更しても『"a = 012"』としたい場合はどうするか。
『deep copy(深いコピー)』すれば良いのです。 deep copyを実装するのに
Marshalモジュールを使います。
Rubyリファレンスマニュアル#Marshal
◆exp. deep copy
a = [0,1,2]
b = Marshal.load(Marshal.dump(a))
b[1] = 3
p "a = " + a.to_s
p "b = " + b.to_s
実行結果は、
"a = 012"
"b = 032"
となり、コピー先bを変更してもコピー元aには影響が出ません。 やっている事は、
Marshal.dump(a)
でマーシャルデータ(オブジェクトをファイルに書き出す際のデータ)を作成して、
b = Marshal.load(Marshal.dump(a))
作成したマーシャルデータをloadしてオブジェクトに戻したものを代入。loadする際に新規にオブジェクト
が生成されるので、deep copyとなるわけです。
deep copyは良く使いそうなので、
def deep_copy(obj)
Marshal.load(Marshal.dump(obj))
end
とかで関数定義しておくと便利そうです。 というか良く使いそうなのでRuby言語側で実装して欲しいm(_ _)m