Deep Clone of array?

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

http://www.ruby-doc.org/core/classes/Object.html#M000379 mentions a
function 'dclone',
but this doesn't seem to exist:

     undefined method `dclone'

···

--
Ronald Fischer <ronald.fischer@venyon.com>
Phone: +49-89-452133-162

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

···

2007/8/9, Ronald Fischer <ronald.fischer@venyon.com>:

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 Aug 09, 2007, at 04:13 , Ronald Fischer 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 Fischer 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'

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

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 Thu, 09 Aug 2007 17:13:09 +0900, Ronald Fischer 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'

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

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

···

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

<snip>

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.

<snip>

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.

···

--
Posted via http://www.ruby-forum.com/\.