Table of contents
1.
Introduction
2.
Object and its ID
2.1.
Object IDs in Ruby
3.
Object Equality in Ruby
3.1.
eql? vs == vs === Methods
3.1.1.
The kernel #=== Method
3.1.2.
The Basic Object #== Method
3.1.3.
The Kernel #eql? Method
3.1.4.
The equal? Method
4.
Frequently Asked Questions
4.1.
Name some of the operators that are used in Ruby.
4.2.
What is the use of Ruby Methods?
4.3.
How can we use Ruby Methods?
4.4.
What do you understand by Ruby Strings?
4.5.
What is the use of global variables in ruby?
5.
Conclusion
Last Updated: Mar 27, 2024

Object identity in ruby

Author Naman Kukreja
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

knowledge of objects is an essential requirement for a developer or a programmer dealing with Ruby language. The Ruby language works on objects. All of its components are related to objects either directly or indirectly.

Working with the object is a bit difficult task if you don’t know where the object is pointing or where it is stored. But don’t worry, we will learn all of them along with how to equate objects while moving further in this blog, so without wasting any more time, let's get on with our topic.

Object and its ID

Ruby is entirely dependent on objects for its work. Ruby can create objects that can perform various operations like inheritance, encapsulation, etc., methods and also consists of various properties.

Every data type is an object in Ruby like arrays, strings, boolean, hashes, integers, etc.

There are many public methods that an object contains which are responsible for its various properties, and with the help of these methods, we can know about the object. Here we will discuss one of the methods, i.e., Object_id.

Object IDs in Ruby

In Ruby, we have a method known as object_id for every object. As the name suggests, it gets the id for an object. It is unique for every object, so it acts as a distinguishable feature in distinguishing between various objects.

It refers to the address in the main memory where the object is stored. This will not change throughout the whole process when an object is present. Let’s understand this better with an example:

name1 = "Joey"
name2 = "Joey"
name1.object_id == name2.object_id # false
name2 = name1
name1.object_id == name2.object_id # true

As you can see in the above example, we have created two variables, both of string type, and initialized both with the same value.

In the next line, we compare the object_id of both to check whether they are the same or not, but we get false. Why?

As the data types of both objects are the same and their contents are also the same answer still comparing object_id of both of them gives false because each variable gets a different Location in the main memory to store their value when they are declared or initialized. So when we assign the same value to different objects, they don’t share the same memory location in the main memory, so the object_ids are different.

But in the second case, when we assign the value of name1 to variable name2 and then compare their object_ids, the answer is true. Why so?

This time, name1 and name2 share the same memory address. This happens because when assigning name2 with name1, we are not creating any other variable. We are just assigning the same address to name2 as that of name1, so after this operation, they have the same address and hence the same object_ids.

Some more examples of object_ids in Ruby are as follows:

num = 22
num.object_id # 76
developer = {"Joey": [8,7,6], "Ross": [0,1,2]}
developer.object_id # 86494844770580
numbers = (85..100).to_a
numbers.object_id  # 86547956985540
programmer = programmer.new("programmer1")
programmer.object_id  # 897425619709960

Integers, boolean and nil variables will give the same object_id again and again.

Now we will learn how to use them in a proper code.

class Developer
  @@colors = {}
  def initialise(name, colors)
    @name = name
    @@colors[object_id] = colors.map(&:to_sym)
  end

 
  def colors_mapping
    return [] unless @@colors[object_id]
    
    @@colors[object_id].each_with_object({}) do |color, hash|
      hash[color] = rand(11..1000)
    end
  end
end

 
u = Developer.new("Joey", ["Black", "Yellow", "Grey", "White"])
p u.colors_mapping

In the above example, we have a developer class that takes the array of colors and a name in the initialize function. We assume a case when the color array will only be accessible in the class and will have no scope outside the class. So we will use a class variable to store the colors.

We will initialize the class variable as an empty hash, and then we will use object_id as the key to store colors in the initialize function.

As the class variable will keep the reference to all the instances created within the class using object_id, so we will make sure that with the collected data, there is no garbage data collected.

Then the color_mapping variable will use the hash key function to find and store the answer.

The value returned by the object_id method is unique and constant for the object's lifetime.

Object Equality in Ruby

There are many methods to compare various objects like ‘eql?’, ‘==’, ‘===’, ‘equal? Methods.

eql? vs == vs === Methods

In ruby, all the classes inherit from the Object class either directly or indirectly. This leads to the object equality logic between the basic object class and kernel module.

Below is the example that uses all the three methods mentioned above for equality checking:

class Hello; end
class World < Hello; end
class Dummy; end

 
hello = Hello.new
world = World.new
dummy = Dummy.new

 
hello == hello # => true
hello == world # => false
hello == dummy # => false

 
hello.eql? hello # => true
hello.eql? world # => false
hello.eql? dummy # => false

 
hello === hello # => true
hello === world # => false
world === hello # => false
hello === dummy # => false

The kernel #=== Method

This method mainly uses check equality in case statements. Any class which can provide meaningful schematics can easily override this method.

For example, it is used in string classes for the override.

The Basic Object #== Method

Most of the core classes in ruby override this method. This method is more particular in some cases due to its property of more permissiveness for object comparison.

For example, the integer class uses this method to override and compare the objects if they are numerically equal or not. 

For this, 1 and 1.0 are numerically equal rather than the fact first one is an integer, and the other is a float.

The Kernel #eql? Method

This will check the quality of two objects by checking their hash key. If they both refer to the same hash key, then it returns true otherwise, false.

To determine the uniqueness of a member, we can use the hash instances.

Let’s understand this with the help of an example:

key = 'key'
other_key = 'key'
key.hash       # => -7531521849152071378
other_key.hash # => -7531521849152071378

 
key.object_id       # => 15935377035880
other_key.object_id # => 15935377028960

 
h = {}

 
h[key] = 'key'
h[other_key] = 'other key'

 
h # => { "key" => "other key" }

Here the other_key and key are two distinct instances.

This method return equality based on the values returned by the hash function. The hash method returns an integer, and we have the same value. In this case, we have the same value for both instances. This means we can override the value contained in the hash entry.

The equal? Method

It is used to verify object identity. It verifies that x is the same object as y. So it is not advised to override this method. Indeed the other three methods that we have learned, like ‘eql?’, ‘==’, ‘===’ are designed to be overridden in object class. The only method that is used to check equality in object iD is equal? Method.

Frequently Asked Questions

Name some of the operators that are used in Ruby.

Some of the operators used in Ruby are Arithmetic, Bitwise, Unary, Ternary, Logical, etc.

What is the use of Ruby Methods?

They prevent us from writing the same code many times in a program. You can refer to them as functions in other programming languages.

How can we use Ruby Methods?

You first need to define them using the def and end keywords. And make sure always to start the method name with a lowercase letter.

What do you understand by Ruby Strings?

Ruby strings manipulate and hold the typical sequence of bytes.

What is the use of global variables in ruby?

You can access the global variable anywhere in the entire program. They can be used with the ‘$’ symbol.

Conclusion

In this article, we have extensively discussed object and its id property and the need for object_id in detail with examples in support of the statements mentioned in the blog, followed by object equality in Ruby with various methods and their proper explanations with examples and the use cases.

Suppose you are not much comfortable with Ruby and still wondering about whether you should proceed with Ruby or not. Don't worry. Coding ninja has covered this. There are the top 8 reasons why Ruby should be your first programming language!.

And for any further queries regarding Ruby, you can visit here. You will get answers to almost all of your queries.

Refer to our guided paths on Coding Ninjas Studio to learn more about DSA, Competitive Programming, React, JavaScript, System Design, etc. Refer to the mock test and problems; If you are looking for practice questions to enter in Tech Giants like Amazon, Microsoft, Uber, etc., you must look at the interview experiences and interview bundle for placement preparations. Do upvote our blog to help other ninjas grow.

Nevertheless, you may consider our paid courses to give your career an edge over others.

 “Happy Coding!”

 

Live masterclass