Why isn't there a deep copy method in Ruby? Why isn't there a deep copy method in Ruby? ruby ruby

Why isn't there a deep copy method in Ruby?


I'm not sure why there's no deep copy method in Ruby, but I'll try to make an educated guess based on the information I could find (see links and quotes below the line).

Judging from this information, I could only infer that the reason Ruby does not have a deep copy method is because it's very rarely necessary and, in the few cases where it truly is necessary, there are other, relatively simple ways to accomplish the same task:

As you already know, using Marshal.dump and Marshal.load is currently the recommended way to do this. This is also the approach recommended by Programming Ruby (see excerpts below).

Alternatively, there are at least 3 available implementations found in these gems: deep_cloneable, deep_clone and ruby_deep_clone; the first being the most popular.


Related Information

Here's a discussion over at comp.lang.ruby which might shed some light on this. There's another answer here with some associated discussions, but it all comes back to using Marshal.

There weren't any mentions of deep copying in Programming Ruby, but there were a few mentions in The Ruby Programming Language. Here are a few related excerpts:

[…]

Another use for Marshal.dump and Marshal.load is to create deep copies of objects:

def deepcopy(o)  Marshal.load(Marshal.dump(o))end

[…]

… the binary format used by Marshal.dump and Marshal.load is version-dependent, and newer versions of Ruby are not guaranteed to be able to read marshalled objects written by older versions of Ruby.

[…]

Note that files and I/O streams, as well as Method and Binding objects, are too dynamic to be marshalled; there would be no reliable way to restore their state.

[…]

Instead of making a defensive deep copy of the array, just call to_enum on it, and pass the resulting enumerator instead of the array itself. In effect, you’re creating an enumerable but immutable proxy object for your array.


Forget marshalling. The deep_dive gem will solve your problems.

https://rubygems.org/gems/deep_dive


Why can't you use something like this:

new_item = Item.new(old_item.attributes)new_item.save!

This would copy all the attributes from existing item to new one, without issues. If you have other objects, you can just copy them individually.

I think it's the quickest way to copy an object