class User
def initialize(attr)
@attr = attr
end
def add_name
@attr[:name] = 'Foo Bar'
@attr
end
end
user = {}
User.new(user).add_name
user
=> {:name=>"Foo Bar"}
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (5)
I'm not sure I understood what your question is.
In your example
@attr
is a hash, which is a mutable structure, when you calladd_name
the object containing the hash mutates it.The line
User.new(user).add_name
is a shortcut for
So you're not using the
User
class, but an instance (object) of such class. By callingadd_name
you modify the instance state,@attr
it make sense if
But why we have same result if do :
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:
as you can see the hash has been changed, but the variable with the number hasn't.
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.
Thanks!!
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