2012-08-01 84 views
12

What's the difference between Ruby's dup and clone methods?描述了dupclone的行爲差異。但是什麼時候應該使用dup,何時應該用clone代替?何時使用dup以及何時在Ruby中使用克隆?

討論爲什麼他們使用dup而不是clone的實際項目的例子,反之亦然,對於這個問題來說很理想。

或者,爲什麼存在兩種不同方法的解釋會有所幫助。這可能是指Ruby的創建者的聲明,或者是影響Ruby的語言中對dupclone等方法的檢查。

+0

[Ruby的dup和clone方法之間有什麼區別?]可能的重複(http://stackoverflow.com/questions/10183370/whats-the-difference-between-rubys-dup-and-clone-methods) – OlehZiniak 2015-12-11 14:46:18

回答

7

這是事實,clone複製對象的frozen狀態,而dup並不:

o = Object.new 
o.freeze 

o.clone.frozen? 
#=> true 

o.dup.frozen? 
#=> false 

clone也將複製對象的單例方法,而dup不會:

o = Object.new 
def o.foo 
    42 
end 

o.clone.respond_to?(:foo) 
#=> true 

o.dup.respond_to?(:foo) 
#=> false 

這導致我認爲clone有時被理解爲提供比dup「更深」的副本。以下是有關的話題一些報價:

Comment on ActiveRecord::Base#initialize_dup from Rails 3

受騙對象沒有ID分配的,將被視爲新記錄。注意 這是一個「淺」副本,因爲它只複製對象的屬性 ,而不是它的關聯。 「深」副本的範圍具體是應用程序 ,因此留給應用程序根據其需要實施。根據 。

An article about deep copies in Ruby

還有另外一個值得一提的是,clone方法。 clone方法與dup的做法相同,但有一個重要的區別:預計對象會覆蓋此方法,並且可以執行深度複製。

But then again, theres deep_dup in Rails 4

返回對象的深層副本,如果它是可複製的。如果不可複製,則返回self

and also ActiveRecord::Core#dup and #clone in Rails 4

clone - 等同於Ruby的克隆方法。這是一個「淺」副本。被警告你的屬性不會被複制。 [...]如果您需要屬性散列的副本,請使用#dup方法。

這意味着在這裏,單詞dup用於再次指代深度克隆。據我所知,社區似乎沒有達成共識,除非你需要使用clonedup,當你需要任何一方的特定副作用時。

最後,我在Ruby代碼中看到dup的次數要多於clone。我從未使用clone到目前爲止,我不會直到我明確需要。

+0

現在看起來像你必須使用'dup',除非你有理由使用'clone'('dup'似乎更簡單)。但也許這是因爲我現在關心重複哈希。所以我不關心凍結狀態和單身人士課程。 – 2015-01-15 04:12:16

4

這兩個DUP &克隆可用於創建對象的淺表副本。兩者都複製obj的實例變量。但我們需要在使用方面有所選擇。這些之間

很少差異是

1)CLONE拷貝都冷凍和一個對象,其中作爲DUP僅複製污點的對象的狀態的玷污狀態。

2)使用CLONE可以複製對象的任何單例方法,但DUP不支持這種方法。

CLONE用於複製對象,包括其內部狀態,DUP通常使用後代對象的類來創建新實例。

我在使用DUP複製ActiveRecord行時遇到了一些痛苦的經歷,最終失去了原來的一個,與CLONE一樣工作得很好。

當我把自己裹在混亂中,我發現它明確在Article of Open Source is Wide Open

+0

「有三種方式可以在Ruby中複製:#dup,#clone和'='。」 - '='拷貝怎麼樣? – 2012-08-01 05:20:19

+0

我並沒有深入瞭解'='的複製方式,但它也是一個淺拷貝。下面是一個[很好的例子](http://thingsaaronmade.com/blog/ruby-shallow-copy-surprise.html),但總之賦值運算符不會複製值,它只是複製對對象的引用 – 2012-08-01 11:04:51

+0

只需注意:'Marshal :: load(Marshal.dump(foo))'有效,但可能會導致數據庫模型出現問題。 – sandstrom 2012-08-30 16:25:10

相關問題