1
class Foo
  def bar
    @instance_variable = [['first']]

    # make a duplicate object with the :dup method
    local_variable=@instance_variable.dup

    # They have different object_id
    p @instance_variable.object_id
    p local_variable.object_id


    local_variable.each{|n|n.push('second')}
    @instance_variable
  end
end

f=Foo.new
p f.bar

=> 2000
=> 2002
=> [["first", "second"]]

It seems that the local_variable still references to the @instance_variable, although it is a different object. This behaviour is both with the push and unshift in the each block. With a normal assignment like local_variable='second', the result is as expected => [['first']]

I don't understand why local_variable.each{|n|n.push('second')} has an effect on the @instance_variable

Using Ruby-1.9.2p318

2 Answers 2

2

Both local_variable and @instance_variable have references to the same object, the inner array ['first']. And because it's a mutable Array, you can effect changes to one array through the other.

Object#dup in Ruby provides a shallow copy. In order to make a deep copy of an Array, you'd need to write some code (or find a library) that recursively walks the data structure, deep-cloning its pieces of mutable state.

Sign up to request clarification or add additional context in comments.

1 Comment

The easy way to do a deep copy is to marshal and unmarshal the array. That will completely reconstruct the object graph, assuming everything in there is amenable to marshaling (not every object necessarily is).
1

The problem is you're not testing the right object. You say:

p @instance_variable.object_id
p local_variable.object_id

But that's not the object you're going to push onto. Try this instead:

p @instance_variable[0].object_id
p local_variable[0].object_id

They are the same object.

In other words, it is not the case that changing local_variable changes @instance_variable, but it just so happens that they both contain a reference to the same object, so obviously changing that object as pointed to by one changes that object as pointed to by the other.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.