EMBLEM
EMBLEM

Reputation: 2265

How do I copy a Ruby array member when I copy an object?

I have a class that has as one of its members an array. I need to copy objects of this class quite a lot. I have found that if I copy the object, even using clone, the array members still refer to the same array:

 class MyClass
   def initialize(a, b, items)
     @a = a
     @b = b
     @items = items
     end
   attr_accessor :a, :b, :items
   end
 => nil 
2.1.5 :009 > test = MyClass.new(2, 3, [1, 2, 3])
 => #<MyClass:0x0000000231e7f8 @a=2, @b=3, @items=[1, 2, 3]> 
2.1.5 :010 > newtest = test.clone
 => #<MyClass:0x00000002312368 @a=2, @b=3, @items=[1, 2, 3]> 
2.1.5 :011 > newtest.a = 55
 => 55 
2.1.5 :012 > newtest
 => #<MyClass:0x00000002312368 @a=55, @b=3, @items=[1, 2, 3]> 
2.1.5 :013 > test
 => #<MyClass:0x0000000231e7f8 @a=2, @b=3, @items=[1, 2, 3]> 
2.1.5 :014 > newtest.items[1] = nil
 => nil 
2.1.5 :015 > newtest
 => #<MyClass:0x00000002312368 @a=55, @b=3, @items=[1, nil, 3]> 
2.1.5 :016 > test
 => #<MyClass:0x0000000231e7f8 @a=2, @b=3, @items=[1, nil, 3]> 

How can I copy the array over with the object?

Upvotes: 0

Views: 51

Answers (2)

Rustam Gasanov
Rustam Gasanov

Reputation: 15791

You can use Marshal core class for this, change your line

newtest = test.clone

to

newtest = Marshal.load(Marshal.dump(test))

Upvotes: 2

Leo Gasparrini
Leo Gasparrini

Reputation: 171

We have a native implementation to perform deep clones of ruby objects: ruby_deep_clone

Install it with gem:

gem install ruby_deep_clone

Example usage:

require "deep_clone"
object = SomeComplexClass.new()
cloned_object = DeepClone.clone(object)

Upvotes: 1

Related Questions