dup vs clone in Ruby
TL;DR:
- clone duplicates most of the things (including singleton methods, freeze state, etc.)
- dup creates “shallow copy”
Let’s create simple Person class and one person object with singleton method.
class Person
attr_accessor :name
end
person = Person.new
person.name = "Toni"
def person.say_name
"My name is #{name}"
end
person.say_name # => "My name is Toni"
Let’s se what happens if we try to access singleton person method with dup or clone.
class Person
attr_accessor :name
end
person = Person.new
person.name = "Toni"
def person.say_name
"My name is #{name}"
end
cloned_person = person.clone
dup_person = person.dup
cloned_person.say_name # => "My name is Toni"
dup_person.say_name # => NoMethodError: undefined method `say_name'
We just found the first difference between dup and clone. Let’s also freeze the person before duplicating the object and see what happens.
class Person
attr_accessor :name
end
person = Person.new
person.name = "Toni"
person.freeze
cloned_person = person.clone
dup_person = person.dup
dup_person.name = "Joe"
cloned_person.name = "Joe" # ~> FrozenError: can't modify frozen Person
The best thing to remember the difference betwen dup and clone is that dup is a “shallow” copy and clone make almost exact copy of the object.