简体   繁体   English

何时使用dup,何时在Ruby中使用clone?

[英]When to use dup, and when to use clone in Ruby?

What's the difference between Ruby's dup and clone methods? Ruby的dup和clone方法有什么区别? describes the difference in the behavior of dup and clone . 描述了dupclone的行为差异。 But when should I use dup , and when should I use clone instead? 但是什么时候应该使用dup ,什么时候应该使用clone呢?

Examples from actual projects which discuss why they used dup rather than clone, or vice versa, would be ideal for this question. 实际项目的例子讨论了为什么他们使用dup而不是克隆,反之亦然,这对于这个问题是理想的。

Alternatively, an explanation of why the two different methods exist would be helpful. 或者,解释为什么存在两种不同的方法会有所帮助。 This could refer to statements from the creators of Ruby, or an examination of methods like dup and clone in languages that influenced Ruby. 这可以参考Ruby创建者的语句,或者检查影响Ruby的语言中的dupclone等方法。

It is true that clone copies the frozen state of an object, while dup does not: 确实, clone复制对象的frozen状态,而dup不会:

o = Object.new
o.freeze

o.clone.frozen?
#=> true

o.dup.frozen?
#=> false

clone will also copy the singleton methods of the object while dup does not: clone也会复制对象的单例方法,而dup不会:

o = Object.new
def o.foo
  42
end

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

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

Which leads me to the assumption that clone is sometimes understood as to provide a "deeper" copy than dup . 这导致我假设clone有时被理解为提供比dup更“深”的副本。 Here are some quotes about the topic: 以下是有关该主题的一些引用:

Comment on ActiveRecord::Base#initialize_dup from Rails 3 : 从Rails 3评论ActiveRecord::Base#initialize_dup

Duped objects have no id assigned and are treated as new records. Duped对象没有分配id并被视为新记录。 Note that this is a "shallow" copy as it copies the object's attributes only, not its associations. 请注意,这是一个“浅”副本,因为它只复制对象的属性,而不是它的关联。 The extent of a "deep" copy is application specific and is therefore left to the application to implement according to its need. “深层”副本的范围是特定于应用程序的,因此留给应用程序根据其需要实现。

An article about deep copies in Ruby : 关于Ruby中的深层副本的文章

There is another method worth mentioning, clone . 还有另一种值得一提的方法, clone The clone method does the same thing as dup with one important distinction: it's expected that objects will override this method with one that can do deep copies. clone方法与dup完全相同,只有一个重要区别:预期对象将使用可以执行深层复制的方法覆盖此方法。

But then again, theres deep_dup in Rails 4 : deep_dup回来,在Rails 4中的theres deep_dup

Returns a deep copy of object if it's duplicable. 如果对象是可复制的,则返回该对象的深层副本。 If it's not duplicable, returns self . 如果它不可重复,则返回self

and also ActiveRecord::Core#dup and #clone in Rails 4 : 还有Rails 4中的ActiveRecord::Core#dup#clone

clone — Identical to Ruby's clone method. clone - 与Ruby的clone方法相同。 This is a "shallow" copy. 这是一个“浅薄”副本。 Be warned that your attributes are not copied. 请注意,不会复制您的属性。 [...] If you need a copy of your attributes hash, please use the #dup method. [...]如果您需要属性哈希的副本,请使用#dup方法。

Which means that here, the word dup is used to refer to a deep clone again. 这意味着,在这里, dup一词再次用于指代深度克隆。 As far as I can see, there seems to be no consensus in the community, except that you should use clone and dup in the case when you need a specific side effect of either one. 据我所知,社区似乎没有达成共识,除非你需要使用clonedup ,当你需要任何一个的特定副作用时。

Finally, I see dup much more often in Ruby code than clone . 最后,我在Ruby代码中看到dup比使用clone更常见。 I have never used clone so far, and I won't until I explicitly need to. 到目前为止,我从未使用过clone ,直到我明确需要,我才会这样做。

Both DUP & CLONE can be used to create shallow copy of an object. DUP和CLONE都可用于创建对象的浅表副本。 Both copies the instance variables of obj. 两者都复制了obj的实例变量。 But we need to be selective in their usage. 但我们需要选择使用它们。

Few difference between these are 这些之间几乎没有区别

1) CLONE copies both FROZEN and TAINTED state of an object, where as DUP only copies TAINTED state of an object. 1)CLONE复制对象的FROZEN和TAINTED状态,其中DUP仅复制对象的TAINTED状态。

2) With CLONE you can copy any singleton methods of an object but DUP does not support this. 2)使用CLONE,您可以复制对象的任何单例方法,但DUP不支持此方法。

CLONE is used to duplicate an object, including its internal state, DUP typically uses the class of the descendent object to create the new instance. CLONE用于复制对象,包括其内部状态,DUP通常使用后代对象的类来创建新实例。

I had some bitter experience while using DUP for duplicating an ActiveRecord row, this ended up in losing the original one the same worked fine with CLONE. 我在使用DUP复制ActiveRecord行时遇到了一些痛苦的经历,最终失去原来的一个同样与CLONE一起正常工作。

As I wrapped myself in confusion, I found it clear in an Article of Open Source is Wide Open 当我把自己包裹在混乱之中时,我发现在开源文章中是明确的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM