What's the difference between Ruby's dup and clone methods?描述了dup
和clone
行为的差异。但是我应该何时使用dup
,何时应该使用clone
?
实际项目的例子讨论了为什么他们使用dup而不是克隆,反之亦然,这对于这个问题来说是理想的。
或者,解释为什么存在两种不同的方法会有所帮助。这可以引用Ruby创建者的语句,或者在影响Ruby的语言中检查dup
和clone
等方法。
答案 0 :(得分:8)
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:
Duped对象没有分配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
用于再次引用深度克隆。据我所知,社区中似乎没有达成共识,除非您需要使用clone
和dup
,因为当您需要任何一方的特定副作用时。
最后,我在Ruby代码中看到的dup
比clone
更频繁。到目前为止,我从未使用clone
,直到我明确需要为止,我才赢了。
答案 1 :(得分:5)
DUP和& CLONE可用于创建对象的浅表副本。两者都复制了obj的实例变量。但我们需要选择使用它们。
这些之间的差异很小
1)CLONE复制对象的FROZEN和TAINTED状态,而DUP只复制对象的TAINTED状态。
2)使用CLONE,您可以复制对象的任何单例方法,但DUP不支持此方法。
CLONE用于复制对象,包括其内部状态,DUP通常使用后代对象的类来创建新实例。
在使用DUP复制ActiveRecord行时,我遇到了一些痛苦的经历,最终失去了原来的一个与CLONE一样正常工作。
当我陷入困惑时,我发现Article of Open Source is Wide Open