rubyguides

Hash#default

hash.default(key = nil) -> object

Description

Hash#default returns the default value for a hash — the value returned when you access a key that doesn’t exist. Every hash starts with a default of nil. You can set a default when creating the hash with Hash.new, or change it later with Hash#default=.

A hash with a default value is useful for counting, memoization, and any situation where you’d otherwise need to check if a key exists before using it.

Setting a Default at Creation

h = Hash.new(0)
h[:count]          # => 0
h[:count] += 1
h[:count]           # => 1
h = Hash.new("unknown")
h[:name]           # => "unknown"

Setting a Default After Creation

h = {}
h.default = -1
h[:missing]        # => -1

Getting the Current Default

h = Hash.new
h.default          # => nil

h = Hash.new(99)
h.default          # => 99

Default Proc vs Default Value

When you use a block with Hash.new, Ruby stores a proc instead of a plain value. The proc receives the hash and the missing key, and its return value becomes the default.

h = Hash.new { |hash, key| hash[key] = [] }
h[:foo] << 1
h[:foo] << 2
h[:bar]            # => []
h                  # => {:foo=>[1, 2], :bar=>[]}

With a plain default value, all missing keys return the same object:

h = Hash.new([])        # shared empty array — dangerous
h[:a] << 1
h[:b]                   # => [1]       (same array!)
h                      # => {}        (nothing was stored)

With a proc, each missing key gets its own result:

h = Hash.new { [] }
h[:a] << 1
h[:b]                   # => []        (different array)
h                      # => {}        (still nothing stored — proc didn't store)

To auto-store the proc result, reference the key explicitly inside the block:

h = Hash.new { |hash, key| hash[key] = [] }
h[:items] << "first"
h[:items] << "second"
h[:items]               # => ["first", "second"]

The default Method with an Argument

When called with a key argument, default(key) checks whether the key exists and returns the default only if the key is truly missing — not just if its value is nil.

h = { foo: nil, bar: 1 }
h[:foo]                # => nil
h.default(:foo)        # => nil  (key exists even though value is nil)
h.default(:baz)        # => nil  (key is missing, returns the default)

See Also

  • Hash#fetch — raises KeyError for missing keys instead of returning a default
  • Hash#dig — safely access nested hash values
  • Hash#has_key? — check if a key exists in the hash