Class

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,” =>:

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:

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:

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

And you can mix the styles:

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'}

Common Uses

You can use a Hash to give names to objects:

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

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

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:

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

You can use a Hash to initialize an object:

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

Here are three ways to create a Hash:

  • Method Hash.new

  • Method Hash[]

  • Literal form: {}.


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

Create an empty Hash:

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

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

Create an empty Hash:

h = Hash[]
h # => {}

Create a Hash with initial entries:

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:

h = {}
h # => {}

Create a Hash with initial entries:

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 []):

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

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

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):

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:

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

New entries are added at the end:

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

Updating a value does not affect the order:

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

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

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.

Invalid Hash Keys

An object that lacks method hash cannot be a Hash key:

# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
{BasicObject.new => 0}

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:

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:

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

And damages the Hash index:

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

You can repair the hash index using method rehash:

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:

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

User-Defined Hash Keys

A user-defined class may be used as a Hash key if the hash and eql? methods are overridden to provide meaningful behavior. By default, separate instances refer to separate Hash keys.

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

class Book
  attr_reader :author, :title

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

  def ==(other)
    self.class === other and
      other.author == @author and
      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

For a key that is not found, method [] returns a default value determined by:

  • Its default proc, if the default proc is not nil.

  • Its default value, otherwise.

Default Value

A Hash object's default value is relevant only when its default proc is nil. (Initially, both are nil).

You can retrieve the default value with method default:

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

You can initialize the default value by passing an argument to method Hash.new:

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

You can update the default value with method default=:

h.default = false
h.default # => false

Incidentally, updating the default value (even to nil) also sets the default proc to nil:

h.default_proc = proc { }
h.default = nil
h.default_proc # => nil

When the default proc is nil, method [] returns the value of method default:

h = Hash.new
h.default_proc # => nil
h.default # => nil
h[:nosuch] # => nil
h.default = false
h[:nosuch] # => false

For certain kinds of default values, the default value can be modified thus:

h = Hash.new('Foo')
h[:nosuch] # => "Foo"
h[:nosuch].upcase! # => "FOO"
h[:nosuch] # => "FOO"
h.default = [0, 1]
h[:nosuch] # => [0, 1]
h[:nosuch].reverse! # => [1, 0]
h[:nosuch] # => [1, 0]

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:

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

You can initialize the default proc by calling Hash.new with a block:

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

You can update the default proc with method default_proc=:

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

Incidentally, updating the default proc (even to nil) also sets the default value to nil:

h.default = false
h.default_proc = nil
h.default # => nil

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:

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:

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

However, the proc itself can add a new entry:

h = Hash.new { |hash, key| hash[key] = "Subsequent value for #{key}"; "First value for #{key}" }
h.include?(:nosuch) # => false
h[:nosuch] # => "First value for nosuch"
h.include?(:nosuch) # => true
h[:nosuch] # => "Subsequent value for nosuch"
h[:nosuch] # => "Subsequent value for nosuch"

You can set the default proc to nil, which restores control to the default value:

h.delete(:nosuch)
h.default_proc = nil
h.default = false
h[:nosuch] # => false

Returns true if hash is a proper subset of other_hash, false otherwise:

h1 = {foo: 0, bar: 1}
h2 = {foo: 0, bar: 1, baz: 2}
h1 < h2 # => true
h2 < h1 # => false
h1 < h1 # => false

Raises an exception if other_hash is not a Hash-convertible object:

h = {}
h < 1 # Raises TypeError (no implicit conversion of Integer into Hash)

Returns true if hash is a subset of other_hash, false otherwise:

h1 = {foo: 0, bar: 1}
h2 = {foo: 0, bar: 1, baz: 2}
h1 <= h2 # => true
h2 <= h1 # => false
h1 <= h1 # => true

Raises an exception if other_hash is not a Hash-convertible object:

h = {}
h <= 1 # Raises TypeError (no implicit conversion of Integer into Hash)

Returns true if all of the following are true:

  • object is a Hash object.

  • hash and object have the same keys (regardless of order).

  • For each key key, hash[key] == object[key].

Otherwise, returns false.

Equal:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 2}
h1 == h2 # => true
h3 = {baz: 2, bar: 1, foo: 0}
h1 == h3 # => true

Not equal because of class:

h1 = {foo: 0, bar: 1, baz: 2}
h1 == 1 # false

Not equal because of different keys:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, zab: 2}
h1 == h2 # => false

Not equal because of different values:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 3}
h1 == h2 # => false

Returns true if hash is a proper superset of other_hash, false otherwise:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1}
h1 > h2 # => true
h2 > h1 # => false
h1 > h1 # => false

Raises an exception if other_hash is not a Hash-convertible object:

h = {}
h > 1 # Raises TypeError (no implicit conversion of Integer into Hash)

Returns true if hash is a superset of other_hash, false otherwise:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1}
h1 >= h2 # => true
h2 >= h1 # => false
h1 >= h1 # => true

Raises an exception if other_hash is not a Hash-convertible object:

h = {}
h >= 1 # Raises TypeError (no implicit conversion of Integer into Hash)

Returns a new Hash object populated with the given objects, if any.

The initial default value and default proc are set to nil (see Default Values):

h = Hash[]
h # => {}
h.class # => Hash
h.default # => nil
h.default_proc # => nil

When argument [*2_element_arrays] is given, each element of the outer array must be a 2-element array; returns a new Hash object wherein each 2-element array forms a key-value entry:

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

When arguments *objects are given, the argument count must be an even number; returns a new Hash object wherein each successive pair of arguments has become a key-value entry:

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

When argument hash_convertible_object is given, the argument must be a Hash-convertible object; converts the object and returns the resulting Hash object:

class Foo
  def to_hash
    {foo: 0, bar: 1}
  end
end
Hash[Foo.new] # => {:foo=>0, :bar=>1}

Raises an exception if the argument count is 1, but the argument is not an array of 2-element arrays or a Hash-convertible object:

# Raises ArgumentError (odd number of arguments for Hash):
Hash[:foo]
# Raises ArgumentError (invalid number of elements (3 for 1..2)):
Hash[ [ [:foo, 0, 1] ] ]

Raises an exception if the argument count is odd and greater than 1:

# Raises ArgumentError (odd number of arguments for Hash):
Hash[0, 1, 2]

Raises an exception if the argument is an array containing an element that is not a 2-element array:

# Raises ArgumentError (wrong element type Symbol at 0 (expected array)):
Hash[ [ :foo ] ]

Raises an exception if the argument is an array containing an element that is an array of size different from 2:

# Raises ArgumentError (invalid number of elements (3 for 1..2)):
Hash[ [ [0, 1, 2] ] ]

Raises an exception if any proposed key is not a valid key (see Invalid Hash Keys):

# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
Hash[:foo, 0, BasicObject.new, 1]
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
Hash[ [ [:foo, 0], [BasicObject.new, 1] ] ]

Returns the value associated with the given key, if found:

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

If key is not found, returns a default value (see Default Values):

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

Associates the given value with the given key, and returns value.

If the given key exists, replaces its value with the given value; the ordering is not affected (see Entry Order):

h = {foo: 0, bar: 1}
h[:foo] = 2 # => 2
h.store(:bar, 3) # => 3
h # => {:foo=>2, :bar=>3}

If key does not exist, adds the key and value; the new entry is last in the order (see Entry Order):

h = {foo: 0, bar: 1}
h[:baz] = 2 # => 2
h.store(:bat, 3) # => 3
h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}

Raises an exception if key is invalid (see Invalid Hash Keys):

h = {foo: 0, bar: 1}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h[BasicObject.new] = 2
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.store(BasicObject.new, 2)

Returns true if any element satisfies a given criterion; false otherwise.


With no argument and no block, returns true if self is non-empty; false if empty:

{}.any? # => false
{nil => false}.any? # => true

With argument object and no block, returns true if for any key key h.assoc(key) == object:

h = {foo: 0, bar: 1, baz: 2}
h.any?([:bar, 1]) # => true
h.any?([:bar, 0]) # => false
h.any?([:baz, 1]) # => false

With no argument and a block, calls the block with each key-value pair; returns true if the block returns any truthy value, false otherwise:

h = {foo: 0, bar: 1, baz: 2}
h.any? {|key, value| value < 3 } # => true
h.any? {|key, value| value > 3 } # => false

With argument object and a block, issues a warning ('given block not used') and ignores the block:

h = {foo: 0, bar: 1, baz: 2}
h.any?([:bar, 1]) # => true
h.any?([:bar, 0]) # => false
h.any?([:baz, 1]) # => false

If the given key is found, returns a 2-element Array containing that key and its value:

h = {foo: 0, bar: 1, baz: 2}
h.assoc(:bar) # => [:bar, 1]

Returns nil if key key is not found:

h = {foo: 0, bar: 1, baz: 2}
h.assoc(:nosuch)

Raises an exception if key is invalid (see Invalid Hash Keys) (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>)
h.assoc(BasicObject.new)

Removes all hash entries; returns self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.clear # => {}
h1.equal?(h) # => true # Identity check

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

h = {foo: 0, bar: nil, baz: 2, bat: nil}
h1 = h.compact
h1 # => {:foo=>0, :baz=>2}

Returns self with all its nil-valued entries removed (in place):

h = {foo: 0, bar: nil, baz: 2, bat: nil}
h1 = h.compact!
h1 # => {:foo=>0, :baz=>2}
h1.equal?(h) # => true

Returns nil if no entries were removed:

h = {foo: 0, bar: 1, baz: 2}
h.compact! # => nil
h # => {:foo=>0, :bar=>1, :baz=>2}

Sets self to consider only identity in comparing keys; two keys are considered the same only if they are the same object; returns self.

By default, these two object are considered to be the same key, so s1 will overwrite s0:

s0 = 'x'
s1 = 'x'
s0.equal?(s0) # => false
h = {}
h.compare_by_identity? # => false
h[s0] = 0
h[s1] = 1
h # => {"x"=>1}

After calling #compare_by_identity, the keys are considered to be different, and therefore do not overwrite each other:

h = {}
h1 = h.compare_by_identity # => {}
h1.equal?(h) # => true
h.compare_by_identity? # => true
h[s0] = 0
h[s1] = 1
h # => {"x"=>0, "x"=>1}

Returns true if compare_by_identity has been called, false otherwise:

h = {}
h.compare_by_identity? # false
h.compare_by_identity
h.compare_by_identity? # true

deconstruct_keys

#
No documentation available

With no argument, returns the current default value:

h = {}
h.default # => nil
h.default = false
h.default # => false

With key given, returns the default value for key, regardless of whether that key exists:

h = {}
h.default(:nosuch) # => nil

The returned value will be determined either by the default proc or by the default value. See Default Values.

Sets the default value to value, returning value:

h = {}
h.default # => nil
h.default = false # => false
h.default # => false

See Default Values.

Returns the default proc:

h = {}
h.default_proc # => nil
h.default_proc = proc { |hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc

See Default Values.

Sets the default proc to proc:

h = {}
h.default_proc # => nil
h.default_proc = proc { |hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc
h.default_proc = nil
h.default_proc # => nil

See Default Values.


Raises an exception if proc is not a Proc:

# Raises TypeError (wrong default_proc type Integer (expected Proc)):
h.default_proc = 1

Deletes the entry for the given key and returns its associated value.


If no block is given and key is found, deletes the entry and returns the associated value:

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

If no block given and key is not found, returns nil:

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

If a block is given and key is found, ignores the block, deletes the entry, and returns the associated value:

h = {foo: 0, bar: 1, baz: 2}
h.delete(:baz) { |key| raise 'Will never happen'} # => 2
h # => {:foo=>0, :bar=>1}

If a block is given and key is not found, calls the block and returns the block's return value:

h = {foo: 0, bar: 1, baz: 2}
h.delete(:nosuch) { |key| "Key #{key} not found" } # => "Key nosuch not found"
h # => {:foo=>0, :bar=>1, :baz=>2}

Raises an exception if key is invalid (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.delete(BasicObject.new)

If a block given, calls the block with each key-value pair; deletes each entry for which the block returns a truthy value; returns self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.delete_if { |key, value| value > 0 }
h1 # => {:foo=>0}
h1.equal?(h) # => true #  Identity check

If no block given, returns a new Enumerator:

h = {foo: 0, bar: 1, baz: 2}
e = h.delete_if # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:delete_if>
h1 = e.each { |key, value| value > 0 }
h1 # => {:foo=>0}
h1.equal?(h) # => true #  Identity check

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration):
h.delete_if { |key, value| h[:new_key] = 3 }

Returns the value for a specified object in nested objects.

For nested objects:

  • For each key in keys, calls method #dig on a receiver.

  • The first receiver is self.

  • Each successive receiver is the value returned by the previous call to #dig.

  • The value finally returned is the value returned by the last call to #dig.

Examples:

h = {foo: 0}
h.dig(:foo) # => 0

h = {foo: {bar: 1}}
h.dig(:foo, :bar) # => 1

h = {foo: {bar: {baz: 2}}}
h.dig(:foo, :bar, :baz) # => 2

Returns nil if any key is not found:

h = { foo: {bar: {baz: 2}}}
h.dig(:foo, :nosuch) # => nil

The nested objects may include any that respond to #dig. See:

Example:

h = {foo: {bar: [:a, :b, :c]}}
h.dig(:foo, :bar, 2) # => :c

Raises an exception if any given key is invalid (see Invalid Hash Keys):

# Raises NoMethodError (undefined method `hash' for #<BasicObject>)
h.dig(BasicObject.new)

Raises an exception if any receiver does not respond to #dig:

h = { foo: 1 }
# Raises TypeError: Integer does not have #dig method
h.dig(:foo, 1)

Calls the given block with each key-value pair, returning self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.each_pair {|key, value| puts "#{key}: #{value}"}
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) # => true # Identity check

Output:

foo: 0
bar: 1
baz: 2

Returns an Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.each_pair # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_pair>
h1 = e.each {|key, value| puts "#{key}: #{value}"}
h1 # => {:foo=>0, :bar=>1, :baz=>2}

Output:

foo: 0
bar: 1
baz: 2

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration)
h.each_pair {|key, value| h[:new_key] = 3 }

Calls the given block with each key; returns self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.each_key {|key| puts key }
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) # => true # Identity check

Output:

foo
bar
baz

Returns an Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.each_key # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_key>
h1 = e.each {|key| puts key }
h1 # => {:foo=>0, :bar=>1, :baz=>2}

Output:

foo
bar
baz

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration):
h.each_key {|key| h[:new_key] = 3 }

Calls the given block with each key-value pair, returning self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.each_pair {|key, value| puts "#{key}: #{value}"}
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) # => true # Identity check

Output:

foo: 0
bar: 1
baz: 2

Returns an Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.each_pair # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_pair>
h1 = e.each {|key, value| puts "#{key}: #{value}"}
h1 # => {:foo=>0, :bar=>1, :baz=>2}

Output:

foo: 0
bar: 1
baz: 2

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration)
h.each_pair {|key, value| h[:new_key] = 3 }

Calls the given block with each value; returns self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.each_value {|value| puts value }
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) # => true # Identity check

Output:

0
1
2

Returns an Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.each_value # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_value>
h1 = e.each {|value| puts value }
h1 # => {:foo=>0, :bar=>1, :baz=>2}

Output:

0
1
2

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration):
h.each_value {|value| h[:new_key] = 3 }

Returns true if there are no hash entries, false otherwise:

{}.empty? # => true
{foo: 0, bar: 1, baz: 2}.empty? # => false

Returns true if all of the following are true:

  • object is a Hash object.

  • hash and object have the same keys (regardless of order).

  • For each key key, h[key] eql? object[key].

Otherwise, returns false.

Equal:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 2}
h1.eql? h2 # => true
h3 = {baz: 2, bar: 1, foo: 0}
h1.eql? h3 # => true

Not equal because of class:

h1 = {foo: 0, bar: 1, baz: 2}
h1.eql? 1 # false

Not equal because of different keys:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, zab: 2}
h1.eql? h2 # => false

Not equal because of different values:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 3}
h1.eql? h2 # => false

Returns a hash excluding the given keys and their values.

h = { a: 100, b: 200, c: 300 }
h.except(:a)          #=> {:b=>200, :c=>300}
h.except(:b, :c, :d)  #=> {:a=>100}

Returns the value for the given key.


When neither default nor a block given:

  • If key is found, returns its associated value.

  • Otherwise, raises an exception:

    h = {foo: 0, bar: 1, baz: 2}
    h.fetch(:bar) # => 1
    # Raises KeyError (key not found: :nosuch):
    h.fetch(:nosuch)
    

When default is given, but no block:

  • If key is found, returns its associated value.

  • Otherwise, returns the given default:

    h = {foo: 0, bar: 1, baz: 2}
    h.fetch(:bar, :default) # => 1
    h.fetch(:nosuch, :default) # => :default
    

When a block is given, but no default:

  • If key is found, returns its associated value.

  • Otherwise, calls the block with key, and returns the block's return value.

    h = {foo: 0, bar: 1, baz: 2}
    h.fetch(:bar) { |key| raise 'Ignored'} # => 1
    h.fetch(:nosuch) { |key| "Value for #{key}"} # => "Value for nosuch"
    

When both default and a block are given:

  • Ignores default and issues a warning: 'block supersedes default value argument'.

  • If key is found, returns its associated value.

  • Otherwise, calls the block with key, and returns the block's return value.

    h = {foo: 0, bar: 1, baz: 2}
    h.fetch(:bar, :default) { |key| raise 'Ignored'} # => 1
    h.fetch(:nosuch, :default) { |key| "Value for #{key}"} # => "Value for nosuch"
    

Raises an exception if key is invalid (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):

h.fetch(BasicObject.new)

Returns a new Array containing the values associated with the given keys *keys:

h = {foo: 0, bar: 1, baz: 2}
h.fetch_values(:baz, :foo) # => [2, 0]

Returns a new empty Array if no arguments given:

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

When a block given, calls the block with each missing key, treating the block's return value as the value for that key:

h = {foo: 0, bar: 1, baz: 2}
values = h.fetch_values(:bar, :foo, :bad, :bam) {|key| key.to_s}
values # => [1, 0, "bad", "bam"]

Raises an exception if any given key is not found:

h = {foo: 0, bar: 1, baz: 2}
h.fetch_values(:baz, :nosuch) # Raises KeyError (key not found: :nosuch)

Raises an exception if any given key is invalid (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.fetch_values(:baz, BasicObject.new)

Hash#filter is an alias for Hash#select.

Returns a new Hash object whose entries are those for which the block returns a truthy value:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.select {|key, value| value < 2 }
h1 # => {:foo=>0, :bar=>1}
h1.equal?(h) # => false

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.select # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select>
h1 = e.each {|key, value| value < 2 }
h1 # => {:foo=>0, :bar=>1}
h1.equal?(h) # => false

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration):
h.select {|key, value| h[:new_key] = 3 }

Hash#filter! is an alias for Hash#select!.

Returns self, whose entries are those for which the block returns a truthy value:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.select! {|key, value| value < 2 }
h # => {:foo=>0, :bar=>1}
h1.equal?(h) # => true

Returns nil if no entries were removed:

h = {foo: 0, bar: 1, baz: 2}
h.select! {|key, value| value < 3} # => nil
h # => {:foo=>0, :bar=>1, :baz=>2}

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.select!  # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select!>
h1 = e.each { |key, value| value < 2 }
h1 # => {:foo=>0, :bar=>1}
h1.equal?(h) # => true

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration)
h.select! {|key, value| h[:new_key] = 3 }

Argument level, if given, must be an Integer-convertible object.

Returns a new Array object that is a 1-dimensional flattening of self.


By default, nested Arrays are not flattened:

h = {foo: 0, bar: [:bat, 3], baz: 2}
h.flatten # => [:foo, 0, :bar, [:bat, 3], :baz, 2]

Takes the depth of recursive flattening from argument level:

h = {foo: 0, bar: [:bat, [:baz, [:bat, ]]]}
h.flatten(1) # => [:foo, 0, :bar, [:bat, [:baz, [:bat]]]]
h.flatten(2) # => [:foo, 0, :bar, :bat, [:baz, [:bat]]]
h.flatten(3) # => [:foo, 0, :bar, :bat, :baz, [:bat]]
h.flatten(4) # => [:foo, 0, :bar, :bat, :baz, :bat]

When level is negative, flattens all nested Arrays:

h = {foo: 0, bar: [:bat, [:baz, [:bat, ]]]}
h.flatten(-1) # => [:foo, 0, :bar, :bat, :baz, :bat]
h.flatten(-2) # => [:foo, 0, :bar, :bat, :baz, :bat]

When level is zero, returns the equivalent of to_a :

h = {foo: 0, bar: [:bat, 3], baz: 2}
h.flatten(0) # => [[:foo, 0], [:bar, [:bat, 3]], [:baz, 2]]
h.flatten(0) == h.to_a # => true

Raises an exception if level is not an Integer-convertible object:

h = {foo: 0, bar: [:bat, 3], baz: 2}
# Raises TypeError (no implicit conversion of Symbol into Integer):
h.flatten(:nosuch)

Methods has_key?, key?, and member? are aliases for #include?.

Returns true if key is a key in self, otherwise false:

h = {foo: 0, bar: 1, baz: 2}
h.include?(:bar) # => true
h.include?(:nosuch) # => false

Raises an exception if key is invalid (see Invalid Hash Keys):

# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.include?(BasicObject.new)

Returns true if value is a value in self, otherwise false:

h = {foo: 0, bar: 1, baz: 2}
h.has_value?(1) # => true
h.has_value?(123) # => false

Returns the Integer hash-code for the hash:

h1 = {foo: 0, bar: 1, baz: 2}
h1.hash.class # => Integer

Two Hash objects have the same hash-code if their content is the same (regardless or order):

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {baz: 2, bar: 1, foo: 0}
h2.hash == h1.hash # => true
h2.eql? h1 # => true

Methods has_key?, key?, and member? are aliases for #include?.

Returns true if key is a key in self, otherwise false:

h = {foo: 0, bar: 1, baz: 2}
h.include?(:bar) # => true
h.include?(:nosuch) # => false

Raises an exception if key is invalid (see Invalid Hash Keys):

# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.include?(BasicObject.new)

Replaces the entire contents of self with the contents of other_hash; returns self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.replace({bat: 3, bam: 4})
h1 # => {:bat=>3, :bam=>4}
h1.equal?(h) # => true # Identity check

Raises an exception if other_hash is not a Hash-convertible object:

h = {}
# Raises TypeError (no implicit conversion of Symbol into Hash):
h.replace(:not_a_hash)

Returns a new String containing the hash entries:

h = {foo: 0, bar: 1, baz: 2}
h.inspect # => "{:foo=>0, :bar=>1, :baz=>2}"

Hash#to_s is an alias for Hash#inspect.

Returns a new Hash object with the each key-value pair inverted:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.invert
h1 # => {0=>:foo, 1=>:bar, 2=>:baz}

Overwrites any repeated new keys: (see Entry Order):

h = {foo: 0, bar: 0, baz: 0}
h.invert # => {0=>:baz}

Raises an exception if any value cannot be a key (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: BasicObject.new}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.invert

Calls the block for each key-value pair; retains the entry if the block returns a truthy value; deletes the entry otherwise; returns self.

h = {foo: 0, bar: 1, baz: 2}
h1 = h.keep_if { |key, value| key.start_with?('b') }
h1 # => {:bar=>1, :baz=>2}
h1.object_id == h.object_id # => true

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.keep_if # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:keep_if>
h1 = e.each { |key, value| key.start_with?('b') }
h1 # => {:bar=>1, :baz=>2}
h1.object_id == h.object_id # => true

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration):
h.keep_if { |key, value| h[:new_key] = 3 }

Returns the key for the first-found entry with the given value (see Entry Order):

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

Returns nil if so such value is found:

h.key(:nosuch) # => nil

Methods has_key?, key?, and member? are aliases for #include?.

Returns true if key is a key in self, otherwise false:

h = {foo: 0, bar: 1, baz: 2}
h.include?(:bar) # => true
h.include?(:nosuch) # => false

Raises an exception if key is invalid (see Invalid Hash Keys):

# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.include?(BasicObject.new)

Returns a new Array containing all keys in self:

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

Returns the count of entries in self:

h = {foo: 0, bar: 1, baz: 2}
h.length # => 3

Hash#length is an alias for Hash#size.

Methods has_key?, key?, and member? are aliases for #include?.

Returns true if key is a key in self, otherwise false:

h = {foo: 0, bar: 1, baz: 2}
h.include?(:bar) # => true
h.include?(:nosuch) # => false

Raises an exception if key is invalid (see Invalid Hash Keys):

# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.include?(BasicObject.new)

Returns the new Hash formed by merging each of other_hashes into a copy of self.

Each argument in other_hashes must be a Hash-convertible object.


With arguments and no block:

  • Returns the new Hash object formed by merging each successive Hash in other_hashes into self.

  • Each new-key entry is added at the end.

  • Each duplicate-key entry's value overwrites the previous value.

Example:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge(h1, h2)
h3 # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5}
h3.equal?(h) # => false # Identity check

With arguments and a block:

  • Returns a new Hash object that is the merge of self and each given hash.

  • The given hashes are merged left to right.

  • Each new-key entry is added at the end.

  • For each duplicate key:

    • Calls the block with the key and the old and new values.

    • The block's return value becomes the new value for the entry.

Example:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge(h1, h2) { |key, old_value, new_value| old_value + new_value }
h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}
h3.equal?(h) # => false # Identity check

Ignores an attempt in the block to add a new key:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge(h1, h2) { |key, old_value, new_value| h[:new_key] = 10 }
h3 # => {:foo=>0, :bar=>10, :baz=>2, :bat=>10, :bam=>5}
h3.equal?(h) # => false # Identity check

With no arguments:

  • Returns a copy of self.

  • The block, if given, is ignored.

Example:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.merge
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) # => false # Identity check
h2 = h.merge { |key, old_value, new_value| raise 'Cannot happen' }
h2 # => {:foo=>0, :bar=>1, :baz=>2}
h2.equal?(h) # => false # Identity check

Raises an exception if any given argument is not a Hash-convertible object:

h = {}
# Raises TypeError (no implicit conversion of Integer into Hash):
h.merge(1)

Merges each of other_hashes into self; returns self.

Each argument in other_hashes must be a Hash-convertible object.

Method update is an alias for #merge!.


With arguments and no block:

  • Returns self, after the given hashes are merged into it.

  • The given hashes are merged left to right.

  • Each new entry is added at the end.

  • Each duplicate-key entry's value overwrites the previous value.

Example:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge!(h1, h2) # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5}
h3.equal?(h) # => true # Identity check

With arguments and a block:

  • Returns self, after the given hashes are merged.

  • The given hashes are merged left to right.

  • Each new-key entry is added at the end.

  • For each duplicate key:

    • Calls the block with the key and the old and new values.

    • The block's return value becomes the new value for the entry.

Example:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge!(h1, h2) { |key, old_value, new_value| old_value + new_value }
h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}
h3.equal?(h) # => true # Identity check

Allows the block to add a new key:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge!(h1, h2) { |key, old_value, new_value| h[:new_key] = 10 }
h3 # => {:foo=>0, :bar=>10, :baz=>2, :bat=>10, :new_key=>10, :bam=>5}
h3.equal?(h) # => true # Identity check

With no arguments:

  • Returns self, unmodified.

  • The block, if given, is ignored.

Example:

h = {foo: 0, bar: 1, baz: 2}
h.merge # => {:foo=>0, :bar=>1, :baz=>2}
h1 = h.merge! { |key, old_value, new_value| raise 'Cannot happen' }
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) # => true # Identity check

Raises an exception if any given argument is not a Hash-convertible object:

h = {}
# Raises TypeError (no implicit conversion of Integer into Hash):
h.merge!(1)

Returns a new empty Hash object.

The initial default value and initial default proc for the new hash depend on which form above was used. See Default Values.

If neither argument nor block given, initializes both the default value and the default proc to nil:

h = Hash.new
h # => {}
h.class # => Hash
h.default # => nil
h.default_proc # => nil
h[:nosuch] # => nil

If argument default_value given but no block given, initializes the default value to the given default_value and the default proc to nil:

h = Hash.new(false)
h # => {}
h.default # => false
h.default_proc # => nil
h[:nosuch] # => false

If block given but no argument given, stores the block as the default proc, and sets the default value to nil:

h = Hash.new { |hash, key| "Default value for #{key}" }
h # => {}
h.default # => nil
h.default_proc.class # => Proc
h[:nosuch] # => "Default value for nosuch"

Raises an exception if both argument default_value and a block are given:

# Raises ArgumentError (wrong number of arguments (given 1, expected 0)):
Hash.new(0) { }

Returns a new 2-element Array consisting of the key and value of the first-found entry whose value is == to value (see Entry Order):

h = {foo: 0, bar: 1, baz: 1}
h.rassoc(1) # => [:bar, 1]

Returns nil if no such value found:

h = {foo: 0, bar: 1, baz: 2}
h.rassoc(3) # => nil

Rebuilds the hash table by recomputing the hash index for each key; returns self.

The hash table will have become invalid if the hash value of a key has changed since the entry was created. See Modifying an Active Hash Key.


Raises an exception if called while an iterator is traversing the hash:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (rehash during iteration):
h.each { |x| h.rehash }

Returns a new Hash object whose entries are all those from self for which the block returns false or nil:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.reject {|key, value| key.start_with?('b') }
h1 # => {:foo=>0}

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.reject # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:reject>
h1 = e.each {|key, value| key.start_with?('b') }
h1 # => {:foo=>0}

Returns self, whose remaining entries are those for which the block returns false or nil:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.reject! {|key, value| value < 2 }
h1 # => {:baz=>2}
h1.equal?(h) # => true # Identity check

Returns nil if no entries are removed:

h = {foo: 0, bar: 1, baz: 2}
h.reject! {|key, value| value > 2 } # => nil
h # => {:foo=>0, :bar=>1, :baz=>2}

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.reject! # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:reject!>
h1 = e.each {|key, value| key.start_with?('b') }
h1 # => {:foo=>0}
h1.equal?(h) # => true # Identity check

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration):
h.reject! { |key, value| h[:new_Key] = 3 }

Replaces the entire contents of self with the contents of other_hash; returns self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.replace({bat: 3, bam: 4})
h1 # => {:bat=>3, :bam=>4}
h1.equal?(h) # => true # Identity check

Raises an exception if other_hash is not a Hash-convertible object:

h = {}
# Raises TypeError (no implicit conversion of Symbol into Hash):
h.replace(:not_a_hash)

Duplicates a given hash and adds a ruby2_keywords flag. This method is not for casual use; debugging, researching, and some truly necessary cases like deserialization of arguments.

h = {k: 1}
h = Hash.ruby2_keywords_hash(h)
def foo(k: 42)
  k
end
foo(*[h]) #=> 1 with neither a warning or an error

Checks if a given hash is flagged by Module#ruby2_keywords (or Proc#ruby2_keywords). This method is not for casual use; debugging, researching, and some truly necessary cases like serialization of arguments.

ruby2_keywords def foo(*args)
  Hash.ruby2_keywords_hash?(args.last)
end
foo(k: 1)   #=> true
foo({k: 1}) #=> false

Hash#filter is an alias for Hash#select.

Returns a new Hash object whose entries are those for which the block returns a truthy value:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.select {|key, value| value < 2 }
h1 # => {:foo=>0, :bar=>1}
h1.equal?(h) # => false

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.select # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select>
h1 = e.each {|key, value| value < 2 }
h1 # => {:foo=>0, :bar=>1}
h1.equal?(h) # => false

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration):
h.select {|key, value| h[:new_key] = 3 }

Hash#filter! is an alias for Hash#select!.

Returns self, whose entries are those for which the block returns a truthy value:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.select! {|key, value| value < 2 }
h # => {:foo=>0, :bar=>1}
h1.equal?(h) # => true

Returns nil if no entries were removed:

h = {foo: 0, bar: 1, baz: 2}
h.select! {|key, value| value < 3} # => nil
h # => {:foo=>0, :bar=>1, :baz=>2}

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.select!  # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select!>
h1 = e.each { |key, value| value < 2 }
h1 # => {:foo=>0, :bar=>1}
h1.equal?(h) # => true

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration)
h.select! {|key, value| h[:new_key] = 3 }

Removes the first hash entry (see Entry Order); returns a 2-element Array containing the removed key and value:

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

Returns the default value if the hash is empty (see Default Values):

h = {}
h.shift # => nil

Returns the count of entries in self:

h = {foo: 0, bar: 1, baz: 2}
h.length # => 3

Hash#length is an alias for Hash#size.

Returns a new Hash object containing the entries for the given keys:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.slice(:baz, :foo)
h1 # => {:baz=>2, :foo=>0}
h1.equal?(h) # => false

Raises an exception if any given key is invalid (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.slice(:foo, BasicObject.new)

Associates the given value with the given key, and returns value.

If the given key exists, replaces its value with the given value; the ordering is not affected (see Entry Order):

h = {foo: 0, bar: 1}
h[:foo] = 2 # => 2
h.store(:bar, 3) # => 3
h # => {:foo=>2, :bar=>3}

If key does not exist, adds the key and value; the new entry is last in the order (see Entry Order):

h = {foo: 0, bar: 1}
h[:baz] = 2 # => 2
h.store(:bat, 3) # => 3
h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}

Raises an exception if key is invalid (see Invalid Hash Keys):

h = {foo: 0, bar: 1}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h[BasicObject.new] = 2
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.store(BasicObject.new, 2)

Returns a new Array of 2-element Array objects; each nested Array contains the key and value for a hash entry:

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

For an instance of Hash, returns self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.to_h
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) #  => true # Identity check

For a subclass of Hash, returns a new Hash containing the content of self:

class MyHash < Hash; end
h = MyHash[foo: 0, bar: 1, baz: 2]
h # => {:foo=>0, :bar=>1, :baz=>2}
h.class # => MyHash
h1 = h.to_h
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.class # => Hash

When a block is given, returns a new Hash object whose content is based on the block; the block should return a 2-element Array object specifying the key-value pair to be included in the returned Array:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.to_h {|key, value| [value, key] }
h1 # => {0=>:foo, 1=>:bar, 2=>:baz}

Raises an exception if the block does not return an Array:

h = {foo: 0, bar: 1, baz: 2}
# Raises TypeError (wrong element type Symbol (expected array)):
h1 = h.to_h {|key, value| :array }

Raises an exception if the block returns an Array of size different from 2:

h = {foo: 0, bar: 1, baz: 2}
# Raises ArgumentError (element has wrong array length (expected 2, was 3)):
h1 = h.to_h {|key, value| [0, 1, 2] }

Raises an exception if the block returns an invalid key (see Invalid Hash Keys):

 h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>)
 h1 = h.to_h {|key, value| [BasicObject.new, 0] }

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration):
h.to_h {|key, value| h[:new_key] = 3 }

Returns self:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.to_hash
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) # => true # Identity check

Returns a Proc object that maps a key to its value:

h = {foo: 0, bar: 1, baz: 2}
proc = h.to_proc
proc.class # => Proc
proc.call(:foo) # => 0
proc.call(:bar) # => 1
proc.call(:nosuch) # => nil

to_s

#
No documentation available

Returns a new Hash object; each entry has:

  • A key provided by the block.

  • The value from self.

Transform keys:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_keys {|key| key.to_s }
h1 # => {"foo"=>0, "bar"=>1, "baz"=>2}

Overwrites values for duplicate keys:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_keys {|key| :bat }
h1 # => {:bat=>2}

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_keys # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:transform_keys>
h1 = e.each { |key| key.to_s }
h1 # => {"foo"=>0, "bar"=>1, "baz"=>2}

Raises an exception if the block returns an invalid key (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>)
h.transform_keys {|key| BasicObject.new }

Raises an exception if the block attempts to add a new key:

h = {foo: 0, bar: 1, baz: 2}
# Raises RuntimeError (can't add a new key into hash during iteration)
h.transform_keys {|key| h[:new_key] = 3 }

Returns self with new keys provided by the block:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_keys! {|key| key.to_s }
h1 # => {"foo"=>0, "bar"=>1, "baz"=>2}
h1.equal?(h) # => true # Identity check

Overwrites values for duplicate keys:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_keys! {|key| :bat }
h1 # => {:bat=>2}

Allows the block to add a new entry:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_keys! {|key| h[:new_key] = key.to_s }
h1 # => {:new_key=>"baz", "foo"=>0, "bar"=>1, "baz"=>2}

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_keys! # => #<Enumerator: {"foo"=>0, "bar"=>1, "baz"=>2}:transform_keys!>
h1 = e.each { |key| key.to_s }
h1 # => {"foo"=>0, "bar"=>1, "baz"=>2}

Raises an exception if the block returns an invalid key (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>)
h.transform_keys! {|key| BasicObject.new }

Returns a new Hash object; each entry has:

  • A key from self.

  • A value provided by the block.

Transform values:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_values {|value| value * 100}
h1 # => {:foo=>0, :bar=>100, :baz=>200}

Ignores an attempt in the block to add a new key:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_values {|value| h[:new_key] = 3; value * 100 }
h1 # => {:foo=>0, :bar=>100, :baz=>200}

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_values # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:transform_values>
h1 = e.each { |value| value * 100}
h1 # => {:foo=>0, :bar=>100, :baz=>200}

Returns self, whose keys are unchanged, and whose values are determined by the given block.

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_values! {|value| value * 100}
h1 # => {:foo=>0, :bar=>100, :baz=>200}
h1.equal?(h) # => true # Identity check

Allows the block to add a new entry:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_values! {|value| h[:new_key] = 3; value * 100 }
h1 # => {:foo=>0, :bar=>100, :baz=>200, :new_key=>3}

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_values! # => #<Enumerator: {:foo=>0, :bar=>100, :baz=>200}:transform_values!>
h1 = e.each {|value| value * 100}
h1 # => {:foo=>0, :bar=>100, :baz=>200}

Returns the Hash object created by calling obj.to_hash:

require 'csv' # => true
row = CSV::Row.new(['Name', 'Age'], ['Bob', 45])
row.respond_to?(:to_hash)  # => true
Hash.try_convert(row) # => {"Name"=>"Bob", "Age"=>45}

Returns the given obj if it is a Hash:

h = {}
h1 = Hash.try_convert(h)
h1.equal?(h) # => true # Identity check

Returns nil unless obj.respond_to?(:to_hash):

s = 'foo'
s.respond_to?(:to_hash) # => false
Hash.try_convert(s) # => nil

Raises an exception unless obj.to_hash returns a Hash object:

class BadToHash
  def to_hash
    1
  end
end
bad = BadToHash.new
Hash.try_convert(bad) # Raises TypeError (can't convert BadToHash to Hash (BadToHash#to_hash gives Integer))

Merges each of other_hashes into self; returns self.

Each argument in other_hashes must be a Hash-convertible object.

Method update is an alias for #merge!.


With arguments and no block:

  • Returns self, after the given hashes are merged into it.

  • The given hashes are merged left to right.

  • Each new entry is added at the end.

  • Each duplicate-key entry's value overwrites the previous value.

Example:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge!(h1, h2) # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5}
h3.equal?(h) # => true # Identity check

With arguments and a block:

  • Returns self, after the given hashes are merged.

  • The given hashes are merged left to right.

  • Each new-key entry is added at the end.

  • For each duplicate key:

    • Calls the block with the key and the old and new values.

    • The block's return value becomes the new value for the entry.

Example:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge!(h1, h2) { |key, old_value, new_value| old_value + new_value }
h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}
h3.equal?(h) # => true # Identity check

Allows the block to add a new key:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge!(h1, h2) { |key, old_value, new_value| h[:new_key] = 10 }
h3 # => {:foo=>0, :bar=>10, :baz=>2, :bat=>10, :new_key=>10, :bam=>5}
h3.equal?(h) # => true # Identity check

With no arguments:

  • Returns self, unmodified.

  • The block, if given, is ignored.

Example:

h = {foo: 0, bar: 1, baz: 2}
h.merge # => {:foo=>0, :bar=>1, :baz=>2}
h1 = h.merge! { |key, old_value, new_value| raise 'Cannot happen' }
h1 # => {:foo=>0, :bar=>1, :baz=>2}
h1.equal?(h) # => true # Identity check

Raises an exception if any given argument is not a Hash-convertible object:

h = {}
# Raises TypeError (no implicit conversion of Integer into Hash):
h.merge!(1)

Returns true if value is a value in self, otherwise false:

h = {foo: 0, bar: 1, baz: 2}
h.has_value?(1) # => true
h.has_value?(123) # => false

Returns a new Array containing all values in self:

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

Returns a new Array containing values for the given keys:

h = {foo: 0, bar: 1, baz: 2}
h.values_at(:foo, :baz) # => [0, 2]

Returns an empty Array if no arguments given:

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

Raises an exception if any given key is invalid (see Invalid Hash Keys):

h = {foo: 0, bar: 1, baz: 2}
# Raises NoMethodError (undefined method `hash' for #<BasicObject>):
h.values_at(BasicObject.new)