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

时间:2012-08-01 00:00:18

标签: ruby clone idiomatic dup

What's the difference between Ruby's dup and clone methods?描述了dupclone行为的差异。但是我应该何时使用dup,何时应该使用clone

实际项目的例子讨论了为什么他们使用dup而不是克隆,反之亦然,这对于这个问题来说是理想的。

或者,解释为什么存在两种不同的方法会有所帮助。这可以引用Ruby创建者的语句,或者在影响Ruby的语言中检查dupclone等方法。

2 个答案:

答案 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

  

还有另一种值得一提的方法,cloneclone方法与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代码中看到的dupclone更频繁。到目前为止,我从未使用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