用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