deep_dup() public

Returns a deep copy of hash.

hash = { a: { b: 'b' } }
dup  = hash.deep_dup
dup[:a][:c] = 'c'

hash[:a][:c] # => nil
dup[:a][:c]  # => "c"
Show source
Register or log in to add new notes.
August 25, 2014 - (v3.1.0 - v3.2.13)
1 thank

This method does not correctly dup arrays

Watch out because this method does not correctly dup arrays values.

The bug can be reproduced with the following code:

hash = { 'a' => [1,2,3,4] }
dup  = hash.deep_dup
dup['a'].object_id == hash['a'].object_id # should return true

Rails 4 version does not have this issue because it is completely different implementation.

February 2, 2015
0 thanks

Be careful with cycles

This simplistic implementation (unlike Marshal.load(Marshal.dump(object)) doesn’t handle cycles in objects.

a = {}
b = {a: a}
a[:b] = b
a.deep_dup # SystemStackError: stack level too deep
January 6, 2016
0 thanks

What about Marshal remote code execution risks?

Good suggestion about using Marshal to avoid cycles, astgtciv, but what about the security risks of doing that?

See where it states:

By design, ::load can deserialize almost any class loaded into the Ruby process. In many cases this can lead to remote code
execution if the Marshal data is loaded from an untrusted source.

As a result, ::load is not suitable as a general purpose serialization format and you should never unmarshal user supplied input or other
untrusted data.

If you need to deserialize untrusted data, use JSON or another serialization format that is only able to load simple,primitive’ types such
as String, Array, Hash, etc. Never allow user input to specify arbitrary types to deserialize into.