Ruby中如何复制对象 (deep clone)(转载)

Ruby中如何复制对象 (deep clone)

用Ruby复制一个对象(object)也许没有你想像的那么容易. 今天我google了半天, 作个总结吧.
先从最简单的开始, b = a 是复制吗? 看代码说话:ruby

a= [0,[1,2]]
b=a
b[0]=88
b[1][0]=99
b 
=> [88, [99, 2]]
a 
=> [88, [99, 2]]

从上面代码发现, 一但修改b, 原来的a也同时被改变了. 甚至:jsp

b.equal?(a)
=> true

原来b跟a根本就是同一个object, 只是马甲不同罢了. 因此b = a不是复制.
那 b = a.dup呢??google

仍是看代码:code

a= [0,[1,2]]
b=a.dup
b[0]=88
b[1][0]=99
b
=> [88, [99, 2]]
a
=> [0, [99, 2]]

状况彷佛有所好转, 在修改b后, a仍是有一部分被修改了.(0没有变,但原来的1变成了99).
因此dup有时候是复制(如在Array只有一级时), 但有时不是复制哦.对象

再来一个, b = a.clone呢? 上代码:get

a= [0,[1,2]]
b=a.clone
b[0]=88
b[1][0]=99
b
=> [88, [99, 2]]
a
=> [0, [99, 2]]

状况几乎跟dup如出一辙. 因此clone也不必定能够相信哦!
原来ruby中的dup和clone都是shallow复制, 只针对object的第一级属性.
汗, 难道在Ruby中没有办法复制对像吗? 也不彻底是, 看这个:class

a= [0,[1,2]]
b=Marshal.load(Marshal.dump(a))
b[0]=88
b[1][0]=99
b
=> [88, [99, 2]]
a= [0,[1,2]]
=> [0, [1, 2]]

修改b后a没有被改变!!! 彷佛终于成功找到复制的办法了!!!
为何要加"彷佛"呢? 由于有些object是不能被Marshal.dump的.如:thread

t=Object.new
def t.test; puts ‘test’ end
Marshal.dump(t)
TypeError: singleton can’t be dumped
from (irb):59:in `dump’
from (irb):59

更完善的复制方案能够考虑给ruby增长一个deep clone功能, 能够参考如下连接:
http://d.hatena.ne.jp/pegacorn/20070417/1176817721
http://www.artima.com/forums/flat.jsp?forum=123&thread=40913
好了, 复制这个小问题, 没想到也能引出这么长的文章来, 没想到吧?test

忘记原文地址了,若有侵权,请告知!object

相关文章
相关标签/搜索