Individual values of a hash are read and written using the [] and []= methods:

my_hash = { length: 4, width: 5 }

my_hash[:length] #=> => 4

my_hash[:height] = 9
my_hash #=> {:length => 4, :width => 5, :height => 9 }

By default, accessing a key which has not been added to the hash returns nil, meaning it is always safe to attempt to look up a key’s value:

my_hash = {}

my_hash[:age] # => nil

Hashes can also contain keys in strings. If you try to access them normally it will just return a nil, instead you access them by their string keys:

my_hash = { "name" => "user" }

my_hash[:name]    # => nil
my_hash["name"]   # => user

For situations where keys are expected or required to exist, hashes have a fetch method which will raise an exception when accessing a key that does not exist:

my_hash = {}

my_hash.fetch(:age) #=> KeyError: key not found: :age

fetch accepts a default value as its second argument, which is returned if the key has not been previously set:

my_hash =  {}
my_hash.fetch(:age, 45) #=> => 45

fetch can also accept a block which is returned if the key has not been previously set:

my_hash = {}
my_hash.fetch(:age) { 21 } #=> 21

my_hash.fetch(:age) do |k|
  puts "Could not find #{k}"
end

#=> Could not find age

Hashes also support a store method as an alias for []=:

my_hash = {}

my_hash.store(:age, 45)

my_hash #=> { :age => 45 }

You can also get all values of a hash using the values method:

my_hash = { length: 4, width: 5 }

my_hash.values #=> [4, 5]

Note: This is only for Ruby 2.3+ #dig is handy for nested Hashs. Extracts the nested value specified by the sequence of idx objects by calling dig at each step, returning nil if any intermediate step is nil.

h = { foo: {bar: {baz: 1}}}

h.dig(:foo, :bar, :baz)   # => 1
h.dig(:foo, :zot, :xyz)   # => nil

g = { foo: [10, 11, 12] }
g.dig(:foo, 1)            # => 11