Posted about 1 month ago. Visible to the public.

Using #deep_dup for copying whole hashes and array

"Everything in Ruby is an object". This is also true for nested hashes and arrays. If you copy a hash with #clone or #dup and you modify the copy, you will run into the following behavior:

Copy
original_hash = { foo: { bar: 'original value' } } copied_hash = original_hash.dup copied_hash[:foo][:bar] = 'changed value' original_hash # => { foo: { bar: "changed value" }

This is, because { bar: 'baz' } is an object, which is referenced in :foo. The copy of original_hash still holds the reference to the same object, so altering the value will also affect the copied hash.
This will get more obvious, if you are having references to e.g. ActiveRecord objects.

But in most cases, if you want to copy a hash, you want to get a copy of the whole structure. And this is where #deep_dup comes into play:

Copy
original_hash = { foo: { bar: 'original value' } } copied_hash = original_hash.deep_dup copied_hash[:foo][:bar] = 'changed value' original_hash # => { foo: { bar: "original value" }

How it works:

#deep_dup simply calls itself recursively for arrays and hashes and calls #dup for all other Objects where #duplicable? is true.

Be careful using #deep_dup

Don't use #deep_dup when you are not sure about cyclic dependencies, because you will run into an endless loop:

Copy
a = {} b = {a: a} a[:b] = b a.deep_dup # SystemStackError: stack level too deep

Once an application no longer requires constant development, it needs periodic maintenance for stable and secure operation. makandra offers monthly maintenance contracts that let you focus on your business while we make sure the lights stay on.

Owner of this card:

Avatar
Jakob Scholz
Last edit:
about 1 month ago
by Jakob Scholz
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Jakob Scholz to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more