Deep Clone of array?

Is there a standard way of doing a deep copy of an object (in
particular, of an array)?

class Object - RDoc Documentation mentions a
function ‘dclone’,
but this doesn’t seem to exist:

 undefined method `dclone'

2007/8/9, Ronald F. [email protected]:

Is there a standard way of doing a deep copy of an object (in
particular, of an array)?

copy_of_your_array = Marshal.load(Marshal.dump(your_array))

class Object - RDoc Documentation mentions a
function ‘dclone’,
but this doesn’t seem to exist:

            undefined method `dclone'

I’ve never seen that method. No idea.

Kind regards

robert

On Aug 09, 2007, at 04:13 , Ronald F. wrote:

Is there a standard way of doing a deep copy of an object (in
particular, of an array)?

class Object - RDoc Documentation mentions a
function ‘dclone’,
but this doesn’t seem to exist:

 undefined method `dclone'

Ronald,

I don’t know about a “standard” way, however the method that I use to
deep copy uses built in constructs:

hashish = { :a => “a”, :b => “b”, :c => [“a”,“b”,“c”] } # some
arbitrary object with references to other objects

hashish_deep_copy = Marshal.load( Marshal.dump( hashish ) )

hashish_deep_copy will then be a deep copy of hashish.

Hope this helps,

~Wayne

s///g
Wayne E. Seguin
Sr. Systems Architect & Systems Administrator

On Thu, 09 Aug 2007 17:13:09 +0900, Ronald F. wrote:

Is there a standard way of doing a deep copy of an object (in
particular, of an array)?

class Object - RDoc Documentation mentions a
function ‘dclone’,
but this doesn’t seem to exist:

 undefined method `dclone'

Marshal.load(Marshsl.dump(array))

On Thu, 09 Aug 2007 17:13:09 +0900, Ronald F. wrote:

Is there a standard way of doing a deep copy of an object (in
particular, of an array)?

class Object - RDoc Documentation mentions a
function ‘dclone’,
but this doesn’t seem to exist:

 undefined method `dclone'

It’s annoying – the ruby-doc core documentation includes all of the
standard library, so it’s hard to tell what comes from where. (Perhaps
they can regenerate the documentation?)

Anyway, if you click on the function name, you’ll see the source code:

File lib/rexml/xpath_parser.rb, line 8

def dclone
clone
end

On Aug 09, 2007, at 09:30 , Wayne E. Seguin wrote:

hashish = { :a => “a”, :b => “b”, :c => [“a”,“b”,“c”] } # some
arbitrary object with references to other objects

hashish_deep_copy = Marshal.load( Marshal.dump( hashish ) )

hashish_deep_copy will then be a deep copy of hashish.

I have a library that I include in my projects which defines a
deep_copy method on object:

class Object
def deep_copy( object )
Marshal.load( Marshal.dump( object ) )
end
end

Also please note that this method has some limitations due to
limitations of Marshall. For example you won’t be able to really dump
IO, Proc, Singleton, Binding and a few other objects (Read the
Marshal docs for more info).

I hope this also helps,

~Wayne

s///g
Wayne E. Seguin
Sr. Systems Architect & Systems Administrator

Marshal.load(Marshal.dump(array))

I’m curious, has anybody done any benchmarking of this method?

It seems to me this method would have the same kind of overhead &
performance hit as PHP’s unserialize(serialize(object)).

I had a similar issue with deep copying an array just now…

Instead of using Marshal, I just extended Array with a roll-my-own:

class Array
def dclone
a = []
each { | x | a << x.dclone }
a
end
end

I think this is a much more robust solution, as it avoids added overhead
that may be hiding inside dump/load, and allows for the deep clone to
further use the children’s deep clone methods.

I believe this is what the developers intended, as dclone begins as
simply an alias for clone (for basic objects, there’s no need to go
deeper. Clone something with no children, and dclone will behave
exactly like clone).

This is of course only valid where dclone is defined (likely depends on
the version of ruby you’re using). You can modify the above code to be
something more like this:

class Array
def dclone
a = []
each do | x |
if x.respond_to? :dclone
a << x.dclone
else
a << x.clone
end
end
end
end

I’m avoiding my usual habit of using the ? : trinary operator, for
clarity, here.