[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

problems with dup and clone...

Russell Fulton

8/14/2006 10:56:00 PM

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



--
Posted via http://www.ruby-....

8 Answers

surf

8/15/2006 1:40:00 AM

0

Russell Fulton wrote:
> 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
>
>
>
> --
> Posted via http://www.ruby-....


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-noiwantthedee...

Russell Fulton

8/15/2006 2:37:00 AM

0

Russell Fulton 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.

--
Posted via http://www.ruby-....

Gennady Bystritsky

8/15/2006 3:08:00 AM

0

> -----Original Message-----
> From: list-bounce@example.com
> [mailto:list-bounce@example.com] On Behalf Of Russell Fulton
> Sent: Monday, August 14, 2006 7:37 PM
> To: ruby-talk ML
> Subject: Re: problems with dup and clone...
>
> Russell Fulton 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.

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.

>
> --
> Posted via http://www.ruby-....
>
>

Rick DeNatale

8/15/2006 6:34:00 PM

0

On 8/14/06, Russell Fulton <r.fulton@auckland.ac.nz> 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.denh...

Visit the Project Mercury Wiki Site
http://www.mercuryspace...

Stefan Lang

8/15/2006 7:05:00 PM

0


On Wednesday, August 16, 2006, at 3:34 AM, Rick DeNatale wrote:
>On 8/14/06, Russell Fulton <r.fulton@auckland.ac.nz> 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.denh...
>
>Visit the Project Mercury Wiki Site
>http://www.mercuryspace...
>

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

--
Posted with http://De.... Sign up and save your mailbox.

Russell Fulton

8/15/2006 9:01:00 PM

0

Russell Fulton wrote:
> Russell Fulton 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

--
Posted via http://www.ruby-....

Rick DeNatale

8/15/2006 11:22:00 PM

0

On 8/15/06, Russell Fulton <r.fulton@auckland.ac.nz> wrote:
> Russell Fulton 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.denh...

Russell Fulton

8/16/2006 12:28:00 AM

0

Russell Fulton 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

--
Posted via http://www.ruby-....