2012-08-01 27 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

相关问题