下記サイトによると、
POD(Plain Old Date)は deep copy 、それ以外は shallow copy なので明示的に deep copy が必要。
POD というのは「C++ において C の構造体と互換性を持つクラス」のことをいう。Ruby では… PORO(Plain Old Ruby Object)でいいのだろうか。
- http://en.wikipedia.org/wiki/Plain_old_data_structure
- http://cxx11.blogspot.jp/2011/12/plain-old-data.html
- https://twitter.com/todesking/status/346588798815203328
# deep_copy a = 1 b = a a += 1 puts a #=> 2 puts b #=> 1
# shallow_copy a = [ 1, 2 ] b = a a << 3 puts a #=> [1,2,3] puts b #=> [1,2,3]
Object#dup
や Object#clone
も shallow copy である。
# dup_1 a = [ 1, 2 ] b = a.dup a << 3 puts a #=> [1,2,3] puts b #=> [1,2] できてるっぽいけど!
# dup_2 a = [ [ 1, 2 ] ] b = a.dup a[0] << 3 puts a #=> [[1,2,3]] puts b #=> [[1,2,3]] # ちなみにここで a << 3 puts a #=> [[1,2,3],3] puts b #=> [[1,2,3]] こうなる
ちゃんと deep copy したかったら Marshal を使う必要がある。
# marshalling a = [ [ 1, 2 ] ] b = Marshal.load( Marshal.dump(a) ) # これ! a[0] << 3 puts a #=> [[1,2,3]] puts b #=> [[1,2]]