2012-08-01 19 views
12

What's the difference between Ruby's dup and clone methods? beschreibt den Unterschied im Verhalten von dup und clone. Aber wann sollte ich dup verwenden, und wann sollte ich stattdessen clone verwenden?Wann sollte man dup verwenden und wann sollte ich in Ruby klonen?

Beispiele aus aktuellen Projekten, in denen diskutiert wird, warum sie dup statt clon verwenden oder umgekehrt, wären ideal für diese Frage.

Alternativ könnte eine Erklärung, warum die zwei verschiedenen Methoden existieren, hilfreich sein. Dies könnte sich auf Aussagen der Ersteller von Ruby oder eine Untersuchung von Methoden wie dup und clone in Sprachen beziehen, die Ruby beeinflusst haben.

+0

Mögliches Duplikat von [Was ist der Unterschied zwischen Rubys dup und clone Methoden?] (Http://stackoverflow.com/questions/10183370/whats-the-difference-between-rubys-dup-and-clone-methods) – OlehZiniak

Antwort

7

klar Es ist wahr, dass clone Kopien der frozen Zustand eines Objekts, während dup nicht:

o = Object.new 
o.freeze 

o.clone.frozen? 
#=> true 

o.dup.frozen? 
#=> false 

clone wird auch die Singleton-Methoden des Objekts kopieren, während dup nicht:

Das führt mich zu der Annahme, dass clone manchmal verstanden wird, um eine "tiefere" Kopie als dup zu liefern. Hier sind einige Zitate über das Thema:

Comment on ActiveRecord::Base#initialize_dup from Rails 3:

Duped Objekte haben keine ID zugewiesen und wird als neuer Datensätze behandelt. Hinweis , dass dies eine "flache" Kopie ist, da es nur die Attribute des Objekts kopiert, nicht seine Zuordnungen. Der Umfang einer "tiefen" Kopie ist Anwendung spezifisch und ist daher der Anwendung überlassen, entsprechend zu seinem Bedarf zu implementieren.

An article about deep copies in Ruby:

Es gibt eine andere Methode erwähnenswert, clone. Die Methode clone macht dasselbe wie dup mit einer wichtigen Unterscheidung: Es wird erwartet, dass Objekte diese Methode mit einer Methode überschreiben, die tiefe Kopien erstellen kann.

But then again, theres deep_dup in Rails 4:

Gibt eine tiefe Kopie des Objekts, wenn es kopierbar ist. Wenn es nicht duplizierbar ist, wird zurückgegeben.

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

clone - Identisch mit Verfahren Rubys Klon. Dies ist eine "flache" Kopie. Seien Sie gewarnt, dass Ihre Attribute nicht kopiert werden. [...] Wenn Sie eine Kopie Ihres Attributs Hash benötigen, verwenden Sie bitte die #dup Methode.

Das bedeutet, dass hier das Wort dup verwendet wird, um wieder auf einen tiefen Klon zu verweisen. Soweit ich das beurteilen kann, scheint es in der Community keinen Konsens zu geben, außer dass Sie clone und dup in dem Fall verwenden sollten, wenn Sie eine bestimmte Nebenwirkung von beiden benötigen.

Schließlich sehe ich dup viel häufiger in Ruby-Code als clone. Ich habe noch nie clone verwendet, und ich werde nicht, bis ich explizit brauche.

+0

Momentan sieht es für mich aus, als müsste man 'dup' verwenden, es sei denn, man hat Gründe,' clone' zu ​​verwenden ('dup' scheint einfacher zu sein). Aber vielleicht liegt es daran, dass ich jetzt daran interessiert bin, einen Hash zu duplizieren. Es ist mir also egal, ob es sich um einen eingefrorenen Zustand und eine Singleton-Klasse handelt. –

4

Beide DUP & CLONE kann verwendet werden, um flache Kopie eines Objekts zu erstellen. Beide kopieren die Instanzvariablen von obj. Aber wir müssen in ihrer Verwendung selektiv sein.

Few Unterschied zwischen diesen sind

1) CLONE Kopien sowohl FROZEN und TAINTED Zustand eines Objekts, in dem als einzige DUP Kopien Zustand eines Objekts behaftet.

2) Mit CLONE können Sie alle Singleton-Methoden eines Objekts kopieren, aber DUP unterstützt dies nicht.

CLONE wird verwendet, um ein Objekt zu duplizieren, einschließlich seines internen Status. DUP verwendet normalerweise die Klasse des untergeordneten Objekts, um die neue Instanz zu erstellen.

Ich hatte einige bittere Erfahrung während der Verwendung von DUP für das Duplizieren einer ActiveRecord Zeile, dies endete mit dem Verlust des ursprünglichen, das gleiche funktionierte gut mit CLONE.

Als ich mich in Verwirrung eingewickelt, fand ich es in einem Article of Open Source is Wide Open

+0

"Es gibt drei Arten, in Ruby zu kopieren: #dup, #clone und '='." - Wie funktioniert '=' kopieren? –

+0

Ich gehe nicht tiefer in '=' kopieren, aber es macht auch eine flache Kopie. Hier ist ein [gutes Beispiel] (http://thingsaaronmade.com/blog/ruby-shallow-copy-surprise.html) für den Start, aber zusammenfassend macht der Zuweisungsoperator keine Kopie des Wertes, er kopiert einfach der Hinweis auf das Objekt –

+0

Nur eine Anmerkung: 'Marshal :: load (Marshal.dump (foo))' funktioniert, kann aber Probleme mit Datenbankmodellen verursachen. – sandstrom