Bibek Sharma
Bibek Sharma

Reputation: 3330

Hash variable is changed while being modified in function

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

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

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

violarium
violarium

Reputation: 411

Ruby pass everything by reference except Integer, Floats and Symbols just for convenience.


UPDATE: It's called immediate values.

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


MORE:

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

Related Questions