为什么要在冻结对象上使用Object#clone?

时间:2014-06-06 15:27:35

标签: ruby

好的,所以出于好奇,你有没有理由想在冻结的物体上使用Object#clone?据我了解,使用Object#dupObject#clone的唯一原因是获取现有对象的第二个副本,以便您可以在不更改原始对象的情况下对其进行修改。但Object#clone复制了对象的冻结状态,并且您无法修改冻结的对象,那么您是否有任何理由想要在该上下文中使用它?

在相关的说明中,如果没有用例,是否有任何理由?

f = "Some string"
f.frozen? #=> false
f.freeze
f.frozen? #=> true
f2 = f.clone
f2.frozen? #=> true
f2.equal? f #=> false
# Why bother? You can't change f or f2 anyway, so
# why even copy it at all?

1 个答案:

答案 0 :(得分:4)

有时候(实际上经常)你可能.clone一个结构而不知道或想知道它里面是什么类型的物体,或者它们是否被冻结。

在这种情况下,冻结对象的行为与非冻结对象的行为类似,因此可以满足.clone如何工作的一般期望。澄清一下,.clone包括保留冻结状态(而dup不保留副本中的那个)。保留冻结状态可确保复制的行为方式相同 - 能够修改对象是一个重要的属性和行为。

换句话说,如果冻结的对象没有这样做,它们可能会破坏或导致使用.clone处理通用结构的Ruby代码的复杂化。一个例子可能是构建模板结构的DSL,这些模板结构在使用时会获得.clone d,例如由Sinatra,Rails,Grape等生成的Rack响应处理程序。

注意我并不是说这些库具体深度克隆路由详细信息,我还没有检查过。只是他们有DSL可以创建相当任意结构的副本。它们是类型的系统,它受益于.clone与冻结对象的一般一致行为。