DEV Community 👩‍💻👨‍💻

AW Unad
AW Unad

Posted on

Why class can mutate variable in Ruby?

class User
  def initialize(attr)
    @attr = attr

  def add_name
    @attr[:name] = 'Foo Bar'

user = {}


=> {:name=>"Foo Bar"}

Top comments (5)

rhymes profile image

I'm not sure I understood what your question is.

In your example @attr is a hash, which is a mutable structure, when you call add_name the object containing the hash mutates it.

The line

is a shortcut for

o =

So you're not using the User class, but an instance (object) of such class. By calling add_name you modify the instance state, @attr

awcodify profile image
AW Unad • Edited on

it make sense if

user = {}
user =

But why we have same result if do :

user = {}
rhymes profile image

Ah ok, I understand now, you're asking why the user variable is also mutated, not just @attr inside the object.

Ruby, same as Python, uses variables as containers to objects. In a sense everything is passed as a reference. If the referenced object (the hash) is mutable then such object can be mutated, and all the labels (the variables) that have a copy of that reference will point to the same object that has changed in the meantime.

Instead, if the object referenced by the variable is immutable, then the copy will updated to point to a new object.

For example:

[1] pry(main)> def dosomething(h)
[1] pry(main)*   h[:name] = "Hello"
[1] pry(main)* end
=> :dosomething
[2] pry(main)> o = {}
=> {}
[3] pry(main)> dosomething(o)
=> "Hello"
[4] pry(main)> o
=> {:name=>"Hello"}
[5] pry(main)> def donothing(a)
[5] pry(main)*   a = 4
[5] pry(main)* end
=> :donothing
[6] pry(main)> b = 5
=> 5
[7] pry(main)> donothing(b)
=> 4
[8] pry(main)> b
=> 5
[9] pry(main)>

as you can see the hash has been changed, but the variable with the number hasn't.

Thread Thread
awcodify profile image
AW Unad

Okay. Got it. So if we want to make it immutable, we have to copy it into new variable and modify on the new one.


Thread Thread
rhymes profile image

Yeah, you can clone it (beware of the difference between copy and deep copy) or you can freeze the object and make sure it can't be mutated

Create an Account!
Now it's your turn!
🗒 Share a tutorial
🤔 Reflect on your coding journey
❓ Ask a question

Create an account to join hundreds of thousands of DEV members on their journey.