How to create a deep copy of an object in Ruby?
Deep copy isn't built into vanilla Ruby, but you can hack it by marshalling and unmarshalling the object:
Marshal.load(Marshal.dump(@object))
This isn't perfect though, and won't work for all objects. A more robust method:
class Object def deep_clone return @deep_cloning_obj if @deep_cloning @deep_cloning_obj = clone @deep_cloning_obj.instance_variables.each do |var| val = @deep_cloning_obj.instance_variable_get(var) begin @deep_cloning = true val = val.deep_clone rescue TypeError next ensure @deep_cloning = false end @deep_cloning_obj.instance_variable_set(var, val) end deep_cloning_obj = @deep_cloning_obj @deep_cloning_obj = nil deep_cloning_obj endend
Source:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/43424
I've created a native implementation to perform deep clones of ruby objects.
It's approximately 6 to 7 times faster than the Marshal approach.
https://github.com/balmma/ruby-deepclone
Note that this project is not maintained anymore (last commit in 2017, there are reported issues)
Rails has a recursive method named deep_dup
that will return a deep copy of an object and, on the contrary of dup
and clone
, works even on composite objects (array/hash of arrays/hashes).It's as easy as:
def deep_dup map { |it| it.deep_dup }end