Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
Ruby is a general-purpose, dynamic, reflective, object-oriented programming language. Everything in Ruby is an object. Ruby's development aimed to create a user interface between human programmers and the underlying computational machinery.
Copying a value or object is fundamental in any programming language.
Many principles for copying objects and values have been developed over time.
In this blog, we'll mainly discuss how to create a shallow copy of an object in Ruby.
Shallow Copy and Deep Copy
In Shallow Copy, only the references of an object are copied, not the referenced objects themselves.
The concept of shallow copy is based on creating a bit-wise copy of an item. The values of the copied object are duplicated in the newly formed object.
In Deep Copy, the object is copied together with the object it refers to.
A deep copy works have a shallow copy. Additionally, all objects pointed by reference in the copied object will also be copied.
Let’s learn how shallow copying of objects is done in Ruby.
Dup and Clone Methods
The Object class has two methods for cloning objects that are quite similar. Both clone and dup make a shallow copy of the object they're called on. Only the object references, not the referred objects, are copied if the copied object has one internal state that relates to other objects.
Let’s learn about the above two methods one by one.
Object.dup
The Object.dup method returns a shallow copy of the calling object.
Let’s understand it with an example:-
obj = 'Hello Ninjas!'
list1 = [obj, 50]
list2 = list1.dup #shallow copy of list1 is created in list2
puts obj.object_id
puts list1.first.object_id
puts list2.first.object_id
puts obj
puts list1.first
puts list2.first
You can also try this code with Online Ruby Compiler
We can see all the objects obj, list1.first, and list2.first all have the same object_id. Also, they return the same value as Hello Ninjas!. It means by assigning the return result of list1.dup to list2, a shallow copy of list1 is stored in list2.
We can see that obj is referenced in list2.first. As a result, when obj is modified, list2.first is also modified.
Note: The Object.dup method internally calls the new object copy's initialize_copy method.
Object.clone
The Object.clone method returns a shallow copy of the calling object.
Let’s understand it with an example:-
obj = 'Hello Ninjas!'
list1 = [obj, 50]
list2 = list1.clone #shallow copy of list1 is created in list2
puts obj.object_id
puts list1.first.object_id
puts list2.first.object_id
puts obj
puts list1.first
puts list2.first
You can also try this code with Online Ruby Compiler
We can see all the objects obj, list1.first, and list2.first all have the same object_id. Also, they return the same value as Hello Ninjas!. It means by assigning the return result of list1.clone to list2, a shallow copy of list1 is stored in list2.
We can see that obj is referenced in list2.first. As a result, when obj is modified, list2.first is also modified.
Note: The Object.clone method also internally calls the new object copy's initialize_copy method.
Difference between Clone and Dup Methods
Both Clone and Dup are essentially similar to each other, but there are some more tasks clone does in comparison to dup:-
1.) The clone duplicates a frozen object, whereas dup on a frozen object returns an unfrozen copy.
2.) Any modules with which the object has been extended will be copied when using Object.clone.
3.) When you use Object.clone, all of the original object's object-level methods are cloned.
Object.freeze
In clone, the frozen state of the object is also copied.
In the above example, we can see that the greet object is frozen, and the clone is working with both the frozen and unfrozen objects, but dup is only working with the unfrozen state.
Object.extend
Any modules with which the object has been extended will be copied when using Object.clone. This won’t be the case with Object.dup.
Let’s understand it with an example:-
class Hello
end
module Ninjas
def hello_ninja
puts 'Hello Ninjas!'
end
end
hello = Hello.new
hello.extend Ninjas
hello.hello_ninja
hello.clone.hello_ninja
hello.dup.hello_ninja
You can also try this code with Online Ruby Compiler
In the above example, we can see that when we try to clone the extended object, it gives the output as Hello Ninjas! but when we try to dup, it gives the error.
Object-level Methods
When you use Object.clone, all of the original object's object-level methods are cloned. This won’t be the case with Object.dup.
Let’s understand it with an example:-
class Hello end
hello = Hello.new
def hello.hello_ninja
puts 'Hello Ninjas!'
end
hello.hello_ninja
hello.clone.hello_ninja
hello.dup.hello_ninja
You can also try this code with Online Ruby Compiler
In the above example, we can see that when we try to clone the object-level object, it gives the output as Hello Ninjas! but when we try to dup, it gives the error.
Frequently Asked Questions
What are Objects in Ruby?
In Ruby, everything is an object. All objects have a unique identification; they can also maintain a state and exhibit behavior in response to messages. Usually, these messages are sent out via method calls. A string is an example of a Ruby object.
What is a Class in Ruby?
In Ruby, classes are first-class objects, each being an instance of the class Class.
What is Shallow Copy?
In Shallow Copy, only the references of an object are copied, not the referenced objects themselves.
What is Deep Copy?
In Deep Copy, the object is copied together with the object it refers to.
What are the different methods to perform Shallow Copy in Ruby?
There are two methods, clone and dup, that make a shallow copy of the object they're called on.
Conclusion
In this article, we have extensively discussed Copying Objects in Ruby, a deep and shallow copy, and the different methods to perform the shallow copy in Ruby.