# Problems with dup and clone

**URL:** <https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602>\
**Category:** Ruby\
**Created:** [August 15, 2006, 12:56am UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602 "2006-08-15T00:56:25Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 15, 2006, 12:56am UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/1 "2006-08-15T00:56:25Z")

</div>

In the snippet of code below hosts holds a set of class instances for  
each host in a monitoring program. There are some special host that are  
default entries for unix, windows and other types of systems.

We get the name of the machine to be monitored into $mach and see if we  
have an entry for it, if we don’t then we use one of the defaults.

```
 if ! host then
if type = type_of_host( filename ) then
  host = hosts[mach] = hosts["default-#{type}"].clone
else
  host = hosts[mach] = hosts["default"].clone
end
host.name = mach
  end

```

I have tried both dup and clone to copy the default objects but I always  
seem to end up with the original object in host.

The symptom is that when the second machine uses the default entry it  
gets the same copy as the first one.

I have printed out host and hosts[“default-#{type}”]:

#\<#Class:0xb7537bc4:0xb73e5a00\>  
#\<#Class:0xb7537bc4:0xb73e599c\>

Clearly I’m missing something important!

Russell

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 15, 2006, 4:37am UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/2 "2006-08-15T04:37:24Z")

</div>

Russell F. wrote:

> I have tried both dup and clone to copy the default objects but I always  
> seem to end up with the original object in host.

More investigations reveals that the objects are being at least  
partially copied. ‘simple’ variables (strings etc) are copied by arrays  
are not.

I have managed to work around this by adding a method fix to the class  
which reinitalised the instance arrays to [] and fix’ing the newly  
dup’ed instances.

This appears to be a bug in ruby. I’ll see if I can reproduce it in a  
small program.

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 15, 2006, 2:20pm UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/3 "2006-08-15T14:20:39Z")

</div>

Russell F. wrote:

> if type = type\_of\_host( filename ) then  
> The symptom is that when the second machine uses the default entry it  
> Russell
> 
> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

Not sure if this is any help, but just today I found there is a way to  
do a deepcopy  
using Marshal

google search yields:  
[http://cyll.org/blog/tech/2006-05-26-noiwantthedeepcopy.html](http://cyll.org/blog/tech/2006-05-26-noiwantthedeepcopy.html)

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 15, 2006, 2:20pm UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/4 "2006-08-15T14:20:50Z")

</div>

> but I always  
> which reinitalised the instance arrays to [] and fix’ing the newly  
> dup’ed instances.
> 
> This appears to be a bug in ruby. I’ll see if I can  
> reproduce it in a  
> small program.

As several people have already indicated, Ruby’s clone() and dup()  
perform “shallow copy” by design. To achieve deep copy you can use  
Marshal:

deep\_cloned\_object = Marshal.load(Marshal.dump(object))

Alternatively, you can use YAML instead of Marshal. Its serialized  
output is human readable.

Best,  
Gennady.

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 15, 2006, 8:36pm UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/5 "2006-08-15T20:36:25Z")

</div>

On 8/14/06, Russell F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I have printed out host and hosts[“default-#{type}”]:
> 
> #\<#Class:0xb7537bc4:0xb73e5a00\>  
> #\<#Class:0xb7537bc4:0xb73e599c\>

But those ARE two different instances. The interesting thing is that  
the class in both cases seems to be anonymous.

How did you build hosts? You say that it contains different “class  
instances”

One way to get such anonymous classes would be something like this:

irb(main):040:0\> fd = Foo.dup  
=\> #Class:0xb7d1404c  
irb(main):041:0\> fd.new  
=\> #\<#Class:0xb7d1404c:0xb7d11310\>  
irb(main):042:0\> fd.new  
=\> #\<#Class:0xb7d1404c:0xb7d0f074\>  
irb(main):043:0\> fd.new.equal?(fd.new)  
=\> false

## Note that the two instances have the same oid for their class, (which is the copy of the Foo class), but different oids of their own.

Rick DeNatale

IPMS/USA Region 12 Coordinator  
[http://ipmsr12.denhaven2.com/](http://ipmsr12.denhaven2.com/)

Visit the Project Mercury Wiki Site  
[http://www.mercuryspacecraft.com/](http://www.mercuryspacecraft.com/)

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 15, 2006, 11:00pm UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/6 "2006-08-15T23:00:38Z")

</div>

Russell F. wrote:

> Russell F. wrote:
> 
> > I have tried both dup and clone to copy the default objects but I always  
> > seem to end up with the original object in host.
> 
> More investigations reveals that the objects are being at least  
> partially copied. ‘simple’ variables (strings etc) are copied by arrays  
> are not.
> 
> I have managed to work around this by adding a method fix to the class  
> which reinitalised the instance arrays to [] and fix’ing the newly  
> dup’ed instances.
> 
> This appears to be a bug in ruby. I’ll see if I can reproduce it in a  
> small program.

OK, not a bug but a feature. My copy of the pickaxe was at home and I  
now understand that dup and clone only do shallow copies. I’m wondering  
if I can use initialize\_copy to copy the arrays that I need – it is  
described as a call back – do I just define a method of that name and  
it will be called on copy? I’ll just have to suck and see!

To Rick who was curious about the anonymous classes. Yes they are  
anonymous, this program is a log scanner and I generate a class for each  
host in the config file with its own scanner and alert routine to  
process logs. I read the config file then generate the scanner  
routines on the fly using eval. I’m not sure why I made them anonymous  
they don’t have to be and I may well change it. The code is in svn on  
rubyforge in the selms project. I’ll be updating it soon and doing the  
first beta release in a week or so. I need to do a short web page  
before I get to that point - bloody documentations 😉

Thanks to those who responded to my post 🙂 I did google this but  
clearly not very effectively!

Russell

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 16, 2006, 1:25am UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/7 "2006-08-16T01:25:07Z")

</div>

On 8/15/06, Russell F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Russell F. wrote:

> To Rick who was curious about the anonymous classes. Yes they are  
> anonymous,

My point wasn’t so much that the classes were anonymous, but that  
those instances realy WERE distinct objects, so as far as I can see,  
you don’t have a problem with dup or clone.

–  
Rick DeNatale

[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 16, 2006, 2:27am UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/8 "2006-08-16T02:27:59Z")

</div>

Russell F. wrote:

> OK, not a bug but a feature. My copy of the pickaxe was at home and I  
> now understand that dup and clone only do shallow copies. I’m wondering  
> if I can use initialize\_copy to copy the arrays that I need – it is  
> described as a call back – do I just define a method of that name and  
> it will be called on copy? I’ll just have to suck and see!

final word on this one. Yes initialize\_copy does the trick. Iv’e  
renamed fix to initialize\_copy and taken the calls to it out of the code  
and it all works as it should.

Cheers and thanks,

Russell

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [August 15, 2006, 9:06pm UTC](https://www.ruby-forum.com/t/problems-with-dup-and-clone/64602/9 "2006-08-15T21:06:34Z")

</div>

On Wednesday, August 16, 2006, at 3:34 AM, Rick DeNatale wrote:

> the class in both cases seems to be anonymous.  
> irb(main):042:0\> fd.new  
> [http://ipmsr12.denhaven2.com/](http://ipmsr12.denhaven2.com/)
> 
> Visit the Project Mercury Wiki Site  
> [http://www.mercuryspacecraft.com/](http://www.mercuryspacecraft.com/)

As I recently discovered, arrays don’t get deep copied with dup or  
clone. My guess is that ruby stores a pointer to an array internally  
and _that_ is what gets copied when you clone the object. So both  
copies point to the original array.

\_Kevin  
[www.sciwerks.com](http://www.sciwerks.com)
