Table of contents
1.
Introduction
2.
Variable References and Types of Passes
2.1.
Variables and References
2.2.
Mutability
2.2.1.
Immutable Objects
2.2.2.
Mutable Objects
2.3.
Types of Passes
3.
Object Passing in Ruby
3.1.
Need for Object Passing
3.2.
Evaluation Strategies
3.3.
Pass By Reference
3.4.
Pass By Value
3.5.
Pass by Reference Value
3.6.
Final Mental Model
4.
Frequently Asked Questions
4.1.
What is the difference between calling Super() and super?
4.2.
Why do we use symbols in hash keys instead of strings?
4.3.
In how many ways can a developer write a block in Ruby?
4.4.
What do you understand by Yield in Ruby?
4.5.
How can we access Ruby String elements?
5.
Conclusion
Last Updated: Mar 27, 2024

Object References in Ruby

Author Naman Kukreja
0 upvote

Introduction

The objects are the basic need/ requirement for a programmer or developer who is working with ruby, as all the things are related to objects in one way or another. The objects here are capable of performing various operations like encapsulation, inheritance, etc.

But if we work with objects, we have to use them repeatedly in various functions and operations. Writing them individually every time will be a time-consuming process. So is there any better way to use objects multiple times without creating them every time?

The answer to the above question is yes; We can use objects without creating a new object by either passing them by reference or by value. We will learn about both of them deeply while moving further in the blog, so without wasting any time further, let's get on with our topic.

Variable References and Types of Passes

Here, we will learn how ruby manipulates objects and variables, and how objects are passed between various programs in ruby. You might wonder what is different in Ruby as we just create an object and assign it to a variable, and then we can use that variable to access the object and change its values. 

In languages like Perl and C++, when we assign an object’s value to the variable, it makes a copy of an object, and all the changes made by that variable happen on the copied object but in languages like python and javascript, when we assign an object equal to a variable it links object and variable, so the changes are affected directly to our object.

Variables and References

We can understand the object as some data that stores some information or state. It can be complex like it can represent a database connection or just can store a boolean value like true or false. We can assign objects to variables like this:

>> greeting = ‘Coding Ninjas’
=> "Coding Ninjas"

In the above statements, the ruby tells the greeting to associate its value with a string object with the value ‘Coding Ninjas’.

All the objects in Ruby have their separate object id, which can be obtained by calling ‘#object_id’ on the object in the question. Even the literals line boolean, number, string, nil. All of them have their individual object id:

>> 5.object_id
=> 11
>> n
nil.object_id
=> 8
>> true.object_id
=> 20
>> "abc".object_id
=> 70101471581080

If we reassign the variable, it doesn't mutate the object referenced by that variable. But the variable is bound to a new object. The original object will not be disconnected from the object.

Mutability

Objects can be of two types, i.e., mutable and immutable. The mutable objects can be mutated, meaning their values can be changed, whereas immutable objects cannot be mutated, which means their values cannot be changed. They need to be reassigned again.

Immutable Objects

These are the objects that have to be reassigned when used by variables. In Ruby, boolean values and numbers are immutable. Let’s learn this with an example.

>> number = 5
=> 5
>> number
=> 5
>> number = 3 * number
=> 15
>> number
=> 15

One might question that in the above example doesn't 5 changes to 15, so how it is immutable.

No, as we have seen above, we are not reassigning the values. We are creating a new integer value of 15 and assigning it to a number. There is no method available by which we can mutate an immutable object. While reassigning the number, the variable starts to reference another object as it disconnects the variable from the original object.

Mutable Objects

Some objects like numbers and boolean immutable objects in ruby rest are mutable. They allow the changes to its object state. You can perform either complex or more straightforward operations to mutable operations.

You can change the value of part of an object by the setter method. The array method will look like this:

>> a = [1, 2, 3, 4, 5]
>> a[1] = 0       # calls setter method
>> a # => [1, 0, 3, 4, 5]

Now we will see an example of how to mutate array elements with the help of a variable:

>> a = %w(a b c)
=> ["a", "b", "c"]
>> a.object_id
=> 70227178647540
>> a[0] = '-'    # calls `Array#[]=` setter method
=> "-"
>> a
=> ["-", "b", "c"]
>> a.object_id
=> 70227178647540

As you can see in the above example, we use array a and its reference. The original array is not changed as the object id is still the same.

Types of Passes

There are mainly two types of passes. We will have their brief introduction in this blog section as we will learn about them in detail in the further part of this blog.

  • Pass by Reference: In pass by reference, the variable is directly passed into the function, which means any changes made to the variable inside the function will be visible to the user as the original variable will also be changed.
  • Pass by Value: In pass by value, the function receives a copy of the original variable which means any change in the variable inside the function will not affect or be visible on the original variable as the changes are done on a copy.

Object Passing in Ruby

Before directly jumping into pass by reference and pass by the value, we will first have a good grip over basic terms. The developer will come up with these terms when he is learning how data is passed in a specific language. The developer must also know what happens to the original object that is passed or returned from a function. In Ruby, everything is an object, and if it is not, it will be reduced to an object after some operations. The expression can be a variable name, object literal, or a complex expression, but ultimately they will be reduced to an object. After this, ruby makes the object available inside the data, and this is known as object passing.

In addition, the receiver or caller of a method call is the object on which the method is called is the implied argument. We need to include the object methods in our object passing.

In Ruby, operators like ‘[]’, ’*’, ‘!’, etc., are methods. This means that operators have a return value, their operands are the arguments, and their return values are passes like arguments.

We'll use some terminology that's a little sloppy because of all of this generality. Literals, named objects (variables and constants), and complex expressions are all examples of objects. Methods, blocks, procs, lambdas, and even operators are all examples of methods. Actual arguments, operator operands, the method's caller, and a return value are all examples of arguments. This haphazard use of vocabulary is imprecise, but it's easier to follow than repeating ourselves at every turn. 

Need for Object Passing

Most programming languages use pass by value by default but can also use pass by reference when needed. But some of the languages are purely passed by reference or pass by value. Understanding the strategy which is used in object passing will lead you to understand what happens to the object after passing. With this help, we can understand what happens to the original object after passing the changes visible on it.

The fact that the object passing strategy influences what this code prints should demonstrate why you should be familiar with it. Based on this code, it may be straightforward to determine whether ruby utilizes pass by value or pass by reference.

Evaluation Strategies

When forwarding objects, every computer programming language employs some type of evaluation mechanism. When expressions are evaluated and what a method can do with the returned objects is determined by this technique. Strict evaluation strategies are the most typical strategies. Every expression is evaluated and turned into an object before being sent along to a method under rigorous evaluation. Ruby is the only language that implements strict evaluation.

The two most used and common strategies are pass by reference and pass by values. Collectively we can call them to object passing strategies.

Pass By Reference

As the name suggests, the reference of the original object is passed. This establishes an alias between the original object and argument. Both the object and argument refer to the same memory location. Example:

def uppercase(value)
 value.upcase!
end
name = 'Coding'
uppercase(name)
puts name               # CODING

Pass By Value

In this, an object's copy is created and passed as we pass the copy, so any changes made in the copy will not affect the original object. Let's learn this with an example:

def plus(x, y)
 x = x * y
end
a = 5
b = plus(a, 4)
puts a # 5
puts b # 20

Pass by Reference Value

We can say that ruby is passed by reference, and there is nothing wrong with it. In many blogs or articles, you will see that ruby is completely passed by reference, but it is not completely true. The ruby constant or variable does not contain an actual object. Instead, the constant or variable contains a pointer to an object.

Assignment simply modifies the pointer, causing the variable to be bound to a variable object than the one it previously held.

We can alter which object is tied to a variable within a method, but we can't change the initial parameters' binding. If the objects are mutable, we can change them, but the references are immutable as far as the function is concerned.

Given this, it's customary just to state that ruby is passed by reference or pass by value. It's a little confusing, but the two words effectively indicate the same thing: ruby circulates copies of the references. In short, Ruby does not use pass by value or pass by reference but rather a third strategy that combines the two.

Final Mental Model

So, What is the answer to the questions passed by value or reference?

The answer is neither, as most blogs and answers will say that it is passed by reference, but there are three answers to the above question.

  • Pass by reference is accurate as long as your account for immutability and assignment.
  • Pass by reference is not true when the object is mutable.
  • Speaking generally, Ruby acts as a pass-by-reference for immutable objects and a pass-by-value for mutable objects.

Frequently Asked Questions

What is the difference between calling Super() and super?

The super() will involve the parent method without any argument. The super will invoke the parent with the arguments passed to the child.

Why do we use symbols in hash keys instead of strings?

The answer is we can use both, but the symbols are immutable, whereas strings are mutable. So in the case of strings, it increases the time.

In how many ways can a developer write a block in Ruby?

We can write it in two ways, i.e., Inline between braces{} and multiline between doing and end.

What do you understand by Yield in Ruby?

With the help of a yield statement, we can call a block with a value within a method.

How can we access Ruby String elements?

You can access ruby string elements with the help of square brackets []. Within these brackets, write the index or string.

Conclusion

In this article, we have extensively discussed variable reference, mutability types of objects followed by an object passing in ruby with an explanation of each type of passing with suitable examples and with the answer that ruby is passed by reference language or pass by value language.

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