Reputation: 3330
I'm changing local variable params
in some_method
:
def some_method params
params.object_id # => 70163816155080
params[:name] = 'bar'
params.object_id # => 70163816155080 Why is this not changing after I changed the value?
end
details = {name: 'foo'}
details.object_id # => 70163816155080
some_method details
details # => {:name=>"bar"}
Why is it changing the original variable details
? Does Ruby use pass by reference for hash?
Upvotes: 0
Views: 95
Reputation: 230336
Some incorrect assumptions on your part
I'm changing local variable params in some_method
No, you're not. Well, yes, you are changing some state of params
, but the object is not replaced, it stays the same. Hence the persistence of its object_id
. If you were to replace the object, then the object_id would change:
def some_method params
params = { name: 'bar' } # this is a new object with a new object_id
# this assignment won't be visible to the outside
Why is this not changing after I changed the value?
There are languages with immutable data structures. There you have to generate a new version of an object if you want to change some data in it. Ruby is not one of those languages. Its data structures are very mutable.
Why is it changing the original variable details
Because these references refer to the same object in memory. See the many links about "pass-by-reference-by-value" posted in answers and comments here.
Upvotes: 1
Reputation: 411
Ruby pass everything by reference except Integer, Floats and Symbols just for convenience.
immediate values are not pointers: Fixnum, Symbol, true, false, and nil are stored directly in VALUE
You even can't define method for this kind of values:
x = :hello
def x.test; end
Will raise an error
For example, Fixnum http://ruby-doc.org/core-2.2.2/Fixnum.html
Fixnum objects have immediate value. This means that when they are assigned or passed as parameters, the actual object is passed, rather than a reference to that object.
Upvotes: 0