Skip to content
On this page

End of Life Ruby 3.1 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →

class · Ruby 3.1

Hash

< Object include Enumerable 73 instance methods 5 class methods

A Hash maps each of its unique keys to a specific value.

A Hash has certain similarities to an Array, but:

  • An Array index is always an Integer.

  • A Hash key can be (almost) any object.

Hash Data Syntax

The older syntax for Hash data uses the “hash rocket,” =>:

Example
h = {:foo => 0, :bar => 1, :baz => 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

Alternatively, but only for a Hash key that’s a Symbol, you can use a newer JSON-style syntax, where each bareword becomes a Symbol:

Example
h = {foo: 0, bar: 1, baz: 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

You can also use a String in place of a bareword:

Example
h = {'foo': 0, 'bar': 1, 'baz': 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

And you can mix the styles:

Example
h = {foo: 0, :bar => 1, 'baz': 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

But it’s an error to try the JSON-style syntax for a key that’s not a bareword or a String:

# Raises SyntaxError (syntax error, unexpected ':', expecting =>):
h = {0: 'zero'}

Hash value can be omitted, meaning that value will be fetched from the context by the name of the key:

Example
x = 0
y = 100
h = {x:, y:}
h # => {:x=>0, :y=>100}

Common Uses

You can use a Hash to give names to objects:

Example
person = {name: 'Matz', language: 'Ruby'}
person # => {:name=>"Matz", :language=>"Ruby"}

You can use a Hash to give names to method arguments:

Example
def some_method(hash)
  p hash
end
some_method({foo: 0, bar: 1, baz: 2}) # => {:foo=>0, :bar=>1, :baz=>2}

Note: when the last argument in a method call is a Hash, the curly braces may be omitted:

Example
some_method(foo: 0, bar: 1, baz: 2) # => {:foo=>0, :bar=>1, :baz=>2}

You can use a Hash to initialize an object:

Example
class Dev
  attr_accessor :name, :language
  def initialize(hash)
    self.name = hash[:name]
    self.language = hash[:language]
  end
end
matz = Dev.new(name: 'Matz', language: 'Ruby')
matz # => #<Dev: @name="Matz", @language="Ruby">

Creating a Hash

You can create a Hash object explicitly with:

You can convert certain objects to Hashes with:

You can create a Hash by calling method Hash.new.

Create an empty Hash:

Example
h = Hash.new
h # => {}
h.class # => Hash

You can create a Hash by calling method Hash.[].

Create an empty Hash:

Example
h = Hash[]
h # => {}

Create a Hash with initial entries:

Example
h = Hash[foo: 0, bar: 1, baz: 2]
h # => {:foo=>0, :bar=>1, :baz=>2}

You can create a Hash by using its literal form (curly braces).

Create an empty Hash:

Example
h = {}
h # => {}

Create a Hash with initial entries:

Example
h = {foo: 0, bar: 1, baz: 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

Hash Value Basics

The simplest way to retrieve a Hash value (instance method []):

Example
h = {foo: 0, bar: 1, baz: 2}
h[:foo] # => 0

The simplest way to create or update a Hash value (instance method []=):

Example
h = {foo: 0, bar: 1, baz: 2}
h[:bat] = 3 # => 3
h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
h[:foo] = 4 # => 4
h # => {:foo=>4, :bar=>1, :baz=>2, :bat=>3}

The simplest way to delete a Hash entry (instance method delete):

Example
h = {foo: 0, bar: 1, baz: 2}
h.delete(:bar) # => 1
h # => {:foo=>0, :baz=>2}

Entry Order

A Hash object presents its entries in the order of their creation. This is seen in:

  • Iterative methods such as each, each_key, each_pair, each_value.

  • Other order-sensitive methods such as shift, keys, values.

  • The String returned by method inspect.

A new Hash has its initial ordering per the given entries:

Example
h = Hash[foo: 0, bar: 1]
h # => {:foo=>0, :bar=>1}

New entries are added at the end:

Example
h[:baz] = 2
h # => {:foo=>0, :bar=>1, :baz=>2}

Updating a value does not affect the order:

Example
h[:baz] = 3
h # => {:foo=>0, :bar=>1, :baz=>3}

But re-creating a deleted entry can affect the order:

Example
h.delete(:foo)
h[:foo] = 5
h # => {:bar=>1, :baz=>3, :foo=>5}

Hash Keys

Hash Key Equivalence

Two objects are treated as the same \hash key when their hash value is identical and the two objects are eql? to each other.

Modifying an Active Hash Key

Modifying a Hash key while it is in use damages the hash’s index.

This Hash has keys that are Arrays:

Example
a0 = [ :foo, :bar ]
a1 = [ :baz, :bat ]
h = {a0 => 0, a1 => 1}
h.include?(a0) # => true
h[a0] # => 0
a0.hash # => 110002110

Modifying array element a0[0] changes its hash value:

Example
a0[0] = :bam
a0.hash # => 1069447059

And damages the Hash index:

Example
h.include?(a0) # => false
h[a0] # => nil

You can repair the hash index using method rehash:

Example
h.rehash # => {[:bam, :bar]=>0, [:baz, :bat]=>1}
h.include?(a0) # => true
h[a0] # => 0

A String key is always safe. That’s because an unfrozen String passed as a key will be replaced by a duplicated and frozen String:

Example
s = 'foo'
s.frozen? # => false
h = {s => 0}
first_key = h.keys.first
first_key.frozen? # => true

User-Defined Hash Keys

To be useable as a Hash key, objects must implement the methods hash and eql?. Note: this requirement does not apply if the Hash uses compare_by_identity since comparison will then rely on the keys’ object id instead of hash and eql?.

Object defines basic implementation for hash and eq? that makes each object a distinct key. Typically, user-defined classes will want to override these methods to provide meaningful behavior, or for example inherit Struct that has useful definitions for these.

A typical implementation of hash is based on the object’s data while eql? is usually aliased to the overridden == method:

Example
class Book
  attr_reader :author, :title

  def initialize(author, title)
    @author = author
    @title = title
  end

  def ==(other)
    self.class === other &&
      other.author == @author &&
      other.title == @title
  end

  alias eql? ==

  def hash
    @author.hash ^ @title.hash # XOR
  end
end

book1 = Book.new 'matz', 'Ruby in a Nutshell'
book2 = Book.new 'matz', 'Ruby in a Nutshell'

reviews = {}

reviews[book1] = 'Great reference!'
reviews[book2] = 'Nice and compact!'

reviews.length #=> 1

Default Values

The methods [], values_at and dig need to return the value associated to a certain key. When that key is not found, that value will be determined by its default proc (if any) or else its default (initially nil).

You can retrieve the default value with method default:

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

You can set the default value by passing an argument to method Hash.new or with method default=

Example
h = Hash.new(-1)
h.default # => -1
h.default = 0
h.default # => 0

This default value is returned for [], values_at and dig when a key is not found:

Example
counts = {foo: 42}
counts.default # => nil (default)
counts[:foo] = 42
counts[:bar] # => nil
counts.default = 0
counts[:bar] # => 0
counts.values_at(:foo, :bar, :baz) # => [42, 0, 0]
counts.dig(:bar) # => 0

Note that the default value is used without being duplicated. It is not advised to set the default value to a mutable object:

Example
synonyms = Hash.new([])
synonyms[:hello] # => []
synonyms[:hello] << :hi # => [:hi], but this mutates the default!
synonyms.default # => [:hi]
synonyms[:world] << :universe
synonyms[:world] # => [:hi, :universe], oops
synonyms.keys # => [], oops

To use a mutable object as default, it is recommended to use a default proc

Default Proc

When the default proc for a Hash is set (i.e., not nil), the default value returned by method [] is determined by the default proc alone.

You can retrieve the default proc with method default_proc:

Example
h = Hash.new
h.default_proc # => nil

You can set the default proc by calling Hash.new with a block or calling the method default_proc=

Example
h = Hash.new { |hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc
h.default_proc = proc { |hash, key| "Default value for #{key.inspect}" }
h.default_proc.class # => Proc

When the default proc is set (i.e., not nil) and method [] is called with with a non-existent key, [] calls the default proc with both the Hash object itself and the missing key, then returns the proc’s return value:

Example
h = Hash.new { |hash, key| "Default value for #{key}" }
h[:nosuch] # => "Default value for nosuch"

Note that in the example above no entry for key :nosuch is created:

Example
h.include?(:nosuch) # => false

However, the proc itself can add a new entry:

Example
synonyms = Hash.new { |hash, key| hash[key] = [] }
synonyms.include?(:hello) # => false
synonyms[:hello] << :hi # => [:hi]
synonyms[:world] << :universe # => [:universe]
synonyms.keys # => [:hello, :world]

Note that setting the default proc will clear the default value and vice versa.

What’s Here

First, what’s elsewhere. Class Hash:

Here, class Hash provides methods that are useful for:

Class Hash also includes methods from module Enumerable.

Methods for Creating a Hash

::[]

Returns a new hash populated with given objects.

::new

Returns a new empty hash.

::try_convert

Returns a new hash created from a given object.

Methods for Setting Hash State

compare_by_identity

Sets self to consider only identity in comparing keys.

default=

Sets the default to a given value.

default_proc=

Sets the default proc to a given proc.

rehash

Rebuilds the hash table by recomputing the hash index for each key.

Methods for Querying

any?

Returns whether any element satisfies a given criterion.

compare_by_identity?

Returns whether the hash considers only identity when comparing keys.

default

Returns the default value, or the default value for a given key.

default_proc

Returns the default proc.

empty?

Returns whether there are no entries.

eql?

Returns whether a given object is equal to self.

hash

Returns the integer hash code.

has_value?

Returns whether a given object is a value in self.

include?, has_key?, member?, key?

Returns whether a given object is a key in self.

length, size

Returns the count of entries.

value?

Returns whether a given object is a value in self.

Methods for Comparing

#<

Returns whether self is a proper subset of a given object.

#<=

Returns whether self is a subset of a given object.

#==

Returns whether a given object is equal to self.

#>

Returns whether self is a proper superset of a given object

#>=

Returns whether self is a proper superset of a given object.

Methods for Fetching

[]

Returns the value associated with a given key.

assoc

Returns a 2-element array containing a given key and its value.

dig

Returns the object in nested objects that is specified by a given key and additional arguments.

fetch

Returns the value for a given key.

fetch_values

Returns array containing the values associated with given keys.

key

Returns the key for the first-found entry with a given value.

keys

Returns an array containing all keys in self.

rassoc

Returns a 2-element array consisting of the key and value of the first-found entry having a given value.

values

Returns an array containing all values in self/

values_at

Returns an array containing values for given keys.

Methods for Assigning

[]=, store

Associates a given key with a given value.

merge

Returns the hash formed by merging each given hash into a copy of self.

merge!, update

Merges each given hash into self.

replace

Replaces the entire contents of self with the contents of a givan hash.

Methods for Deleting

These methods remove entries from self:

clear

Removes all entries from self.

compact!

Removes all nil-valued entries from self.

delete

Removes the entry for a given key.

delete_if

Removes entries selected by a given block.

filter!, select!

Keep only those entries selected by a given block.

keep_if

Keep only those entries selected by a given block.

reject!

Removes entries selected by a given block.

shift

Removes and returns the first entry.

These methods return a copy of self with some entries removed:

compact

Returns a copy of self with all nil-valued entries removed.

except

Returns a copy of self with entries removed for specified keys.

filter, select

Returns a copy of self with only those entries selected by a given block.

reject

Returns a copy of self with entries removed as specified by a given block.

slice

Returns a hash containing the entries for given keys.

Methods for Iterating

each, each_pair

Calls a given block with each key-value pair.

each_key

Calls a given block with each key.

each_value

Calls a given block with each value.

Methods for Converting

inspect, to_s

Returns a new String containing the hash entries.

to_a

Returns a new array of 2-element arrays; each nested array contains a key-value pair from self.

to_h

Returns self if a Hash; if a subclass of Hash, returns a Hash containing the entries from self.

to_hash

Returns self.

to_proc

Returns a proc that maps a given key to its value.

Methods for Transforming Keys and Values

transform_keys

Returns a copy of self with modified keys.

transform_keys!

Modifies keys in self

transform_values

Returns a copy of self with modified values.

transform_values!

Modifies values in self.

Other Methods

flatten

Returns an array that is a 1-dimensional flattening of self.

invert

Returns a hash with the each key-value pair inverted.

Class methods 5

Instance methods 73

Ruby version changes 2

  1. 3.0