好的,所以出于好奇,你有没有理由想在冻结的物体上使用Object#clone
?据我了解,使用Object#dup
和Object#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?
答案 0 :(得分:4)
有时候(实际上经常)你可能.clone
一个结构而不知道或想知道它里面是什么类型的物体,或者它们是否被冻结。
在这种情况下,冻结对象的行为与非冻结对象的行为类似,因此可以满足.clone
如何工作的一般期望。澄清一下,.clone
包括保留冻结状态(而dup
不保留副本中的那个)。保留冻结状态可确保复制的行为方式相同 - 不能够修改对象是一个重要的属性和行为。
换句话说,如果冻结的对象没有这样做,它们可能会破坏或导致使用.clone
处理通用结构的Ruby代码的复杂化。一个例子可能是构建模板结构的DSL,这些模板结构在使用时会获得.clone
d,例如由Sinatra,Rails,Grape等生成的Rack响应处理程序。
注意我并不是说这些库做具体深度克隆路由详细信息,我还没有检查过。只是他们有DSL可以创建相当任意结构的副本。它们是类型的系统,它受益于.clone
与冻结对象的一般一致行为。