Today Icelab Learned

Kwarg splat arguments create new hashes

I made a method with a “double splat” kwarg argument to accept some options and returned a modified hash:

def singularize_options(**options)
  options = options.dup

  # mutate `options` here...

  options
end

In my usual “don’t mutate things we don’t own” style, I #duped the incoming options before going to work on it.

However, thanks to our dry-rb/rom-rb friend @flash-gordon, I learnt this wasn’t necessary! As he says:

when you capture values with **, Ruby creates a new hash instance so calling .dup is not needed

def foo(**options)
  options.object_id
end

{}.tap { |h| puts foo(h) == h.object_id }
# => false

Now my method can be even simpler:

def singularize_options(**options)
  # mutate `options` here...
  options
end