Hash#update
update(*other_hashes) → self Signature
update(*other_hashes) → self
update(*other_hashes) {|key, old_value, new_value| block } → self
update takes zero or more hash arguments and optionally a block. It always returns self — the same hash object that was modified in place.
Basic Usage
Give update one or more hashes and it merges them into the receiver, overwriting duplicate keys:
h = {a: 1, b: 2}
h.update({b: 3, c: 4})
h # => {:a=>1, :b=>3, :c=>4}
The original hash is modified. update returns the same object it just mutated.
Block Form
When a key appears in both hashes, you can pass a block to resolve the conflict:
h = {items: 5, threshold: 10}
h.update({items: 3, threshold: 12}) { |_key, old, new| old + new }
h # => {:items=>8, :threshold=>22}
The block receives key, old_value, and new_value and its return value becomes the final value for that key. In the example above, the new items value is 5 + 3 = 8, not just 3.
No Arguments
Calling update with no arguments simply returns self unchanged:
h = {x: 1, y: 2}
h.update # => {:x=>1, :y=>2}
h.update { } # => {:x=>1, :y=>2} (block is ignored)
Note that this is not a copy — the method returns the same object. There is no update form that returns a modified copy like merge does.
Multiple Hashes
You can pass multiple hashes. They are merged left to right, so later hashes win on conflicts:
h = {a: 1}
h.update({a: 2}, {a: 3}, {a: 4})
h # => {:a=>4}
Each duplicate key is overwritten by whichever hash came later in the argument list.
Alias for Hash#merge!
update is exactly the same method as Hash#merge! — they share the same implementation. Use whichever name reads better in your context:
h = {x: 1}
h.merge!({y: 2}) # => {:x=>1, :y=>2}
h.update({z: 3}) # => {:x=>1, :y=>2, :z=>3}
Gotchas
Returns self, not a copy. Many Ruby hash methods return a new hash — merge returns a new hash, for example. update returns the mutated original, so be careful not to chain it expecting a copy back.
h = {a: 1}
result = h.update({b: 2})
result.equal?(h) # => true (same object)
TypeError on non-Hash arguments. Each argument must be a Hash. Passing a non-hash raises TypeError:
h = {}
h.update("foo")
# => TypeError: no implicit conversion of String into Hash
No automatic flattening. If you pass a hash containing array values, those arrays are not recursively merged:
h = {nested: {a: 1}}
h.update(nested: {b: 2})
h # => {:nested=>{:b=>2}} # the original :a is gone, not deep-merged
Ruby does not provide a built-in deep merge. The outer key is simply overwritten.
See Also
- Hash#merge — returns a new merged hash without modifying the original
- Hash#merge! — the canonical name for this method
- Hash#dig — safely retrieve nested hash values