What's the difference between Ruby's dup and clone methods? describes the difference in the behavior of dup
and clone
. But when should I use dup
, and when should I use clone
instead?
Examples from actual projects which discuss why they used dup rather than clone, or vice versa, would be ideal for this question.
Alternatively, an explanation of why the two different methods exist would be helpful. This could refer to statements from the creators of Ruby, or an examination of methods like dup
and clone
in languages that influenced Ruby.
The dup() is an inbuilt method in Ruby returns the number itself.
Ruby does provide two methods for making copies of objects, including one that can be made to do deep copies. The Object#dup method will make a shallow copy of an object. To achieve this, the dup method will call the initialize_copy method of that class. What this does exactly is dependent on the class.
We can use the asterisk * operator to duplicate a string for the specified number of times. The asterisk operator returns a new string that contains a number of copies of the original string.
You generally use #clone if you want to copy an object including its internal state. This is what Rails is using with its #dup method on ActiveRecord. It uses #dup to allow you to duplicate a record without its "internal" state (id and timestamps), and leaves #clone up to Ruby to implement.
It is true that clone
copies the frozen
state of an object, while dup
does not:
o = Object.new
o.freeze
o.clone.frozen?
#=> true
o.dup.frozen?
#=> false
clone
will also copy the singleton methods of the object while dup
does not:
o = Object.new
def o.foo
42
end
o.clone.respond_to?(:foo)
#=> true
o.dup.respond_to?(:foo)
#=> false
Which leads me to the assumption that clone
is sometimes understood as to provide a "deeper" copy than dup
. Here are some quotes about the topic:
Comment on ActiveRecord::Base#initialize_dup
from Rails 3:
Duped objects have no id assigned and are treated as new records. Note that this is a "shallow" copy as it copies the object's attributes only, not its associations. The extent of a "deep" copy is application specific and is therefore left to the application to implement according to its need.
An article about deep copies in Ruby:
There is another method worth mentioning,
clone
. Theclone
method does the same thing asdup
with one important distinction: it's expected that objects will override this method with one that can do deep copies.
But then again, theres deep_dup
in Rails 4:
Returns a deep copy of object if it's duplicable. If it's not duplicable, returns
self
.
and also ActiveRecord::Core#dup
and #clone
in Rails 4:
clone
— Identical to Ruby's clone method. This is a "shallow" copy. Be warned that your attributes are not copied. [...] If you need a copy of your attributes hash, please use the#dup
method.
Which means that here, the word dup
is used to refer to a deep clone again. As far as I can see, there seems to be no consensus in the community, except that you should use clone
and dup
in the case when you need a specific side effect of either one.
Finally, I see dup
much more often in Ruby code than clone
. I have never used clone
so far, and I won't until I explicitly need to.
Both DUP & CLONE can be used to create shallow copy of an object. Both copies the instance variables of obj. But we need to be selective in their usage.
Few difference between these are
1) CLONE copies both FROZEN and TAINTED state of an object, where as DUP only copies TAINTED state of an object.
2) With CLONE you can copy any singleton methods of an object but DUP does not support this.
CLONE is used to duplicate an object, including its internal state, DUP typically uses the class of the descendent object to create the new instance.
I had some bitter experience while using DUP for duplicating an ActiveRecord row, this ended up in losing the original one the same worked fine with CLONE.
As I wrapped myself in confusion, I found it clear in an Article of Open Source is Wide Open
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With