문제

Is this behavior correct? I'm running some code like the following:

@a_hash = {:a => 1}
x = @a_hash
x.merge!({:b => 2})

At the end of all that, x's value has been changed as expected but so has the value for @a_hash. I'm getting {:a => 1, :b => 2} as the value for both of them. Is this normal behavior in Ruby?

도움이 되었습니까?

해결책

Yes, instance variable @a_hash and local variable x store the reference to the same Hash instance and when you change this instance (using mutator method merge! that change object in place), these variables will be evaluated to the same value.

You may want to use merge method that create a copy of the object and don't change original one:

@a_hash = {:a => 1}
x = @a_hash
y = x.merge({:b => 2})
# y => {:a => 1, :b => 2}
# x and @a_hash => {:a => 1}

다른 팁

@a_hash is link to x. So if You want @a_hash not changed, you should do like this:

@a_hash = {:a => 1}
x = @a_hash.clone
x.merge!({:b => 2})

Yes, that's normal behavior in ruby (and most other languages). Both x and @a_hash are references to the same object. By calling merge! you change that object and that change in visible through all variables that refer to it.

If you don't want that behavior, you should either not use mutating methods (i.e. use x = x.merge(...) instead) or copy the object before you mutate it (i.e. x = @a_hash.dup).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top