多重配列のdeep copy
Rubyの配列をそのまま代入"="するだけだとメモリの参照先が同じなので同じ値しか返ってきません。
また、.dupや.cloneを使っても多重配列はダメみたいです。浅いコピーなので。。。
そこで配列の深いコピー(deep copy)する方法をメモします。
- 配列のdeep copy
array2 = Marshal.load(Marshal.dump(array1))
- ダメなパタン
array1 = [[1,2,3],[4,5,6],[7,8,9]] array3 = array1 # 参照先は同じ array4 = array1.dup # オブジェクトはコピーされない array5 = array1.clone # オブジェクトはコピーされない array1[1][1] = 10 p array1 # <= [[1, 2, 3], [4, 10, 6], [7, 8, 9]] p array3 # <= [[1, 2, 3], [4, 10, 6], [7, 8, 9]] p array4 # <= [[1, 2, 3], [4, 10, 6], [7, 8, 9]] p array5 # <= [[1, 2, 3], [4, 10, 6], [7, 8, 9]]
ちなみに、Marshal(マーシャリングライブラリ)は、Rubyのオブジェクト(+子孫)をバイナリストリームに変換するためのもの、らしいです。
- Marshal.dumpは、オブジェクトとその子孫オブジェクトをバイナリストリームに変換
- Marshal.loadは、バイナリデータをRubyオブジェクトに変換する
うむ、なるほど。"オブジェクトとその子孫"ってところがdeep copyに該当してそうですね。