Hash#each
hash.each { |key, value| block } -> hash The Hash class provides three primary methods for iterating over key-value pairs: .each, .each_pair, and .each_with_object. Each serves a slightly different purpose depending on whether you need to modify the hash during iteration or accumulate a result in a separate object.
If you are only printing or logging each entry, each and each_pair are the simplest options. When you want to build a separate collection while visiting each key-value pair, each_with_object keeps the accumulator close to the loop and avoids extra temporary variables.
That distinction helps when you are choosing between a method that is mostly about side effects and one that is mostly about building a new object. In practice, each is the broad default, each_pair reads a little more explicitly, and each_with_object is the best fit when you want to accumulate data without mutating an external variable.
.each
The .each method iterates over each key-value pair and yields both to the block. It returns the original hash, making it chainable with other methods.
user = { name: "Alice", age: 30, city: "London" }
user.each do |key, value|
puts "#{key}: #{value}"
end
# Output:
# name: Alice
# age: 30
# city: London
The standard each call on a hash yields both the key and the value to the block, which is the most common iteration pattern. It returns the original hash, so you can chain it with other hash methods after the block runs. When you only need one side of the pair, Ruby provides convenience methods that keep the block signature simpler.
You can also iterate over just keys or just values:
user.each_key { |key| puts key }
# name
# age
# city
user.each_value { |value| puts value }
# Alice
# 30
# London
These shorthand methods are worth remembering because they keep the block signature clean when you only care about one side of the hash. each_key and each_value are also available as standalone iterators with Enumerator support, so you can compose them with map, select, or any other Enumerable method when you need to transform or filter the keys or values separately.
.each_pair
The .each_pair method is identical to .each. Both iterate over key-value pairs and return the hash. Ruby provides both as aliases, though .each is more commonly used.
config = { theme: "dark", font_size: 14, auto_save: true }
config.each_pair do |key, value|
puts "#{key} = #{value}"
end
In everyday code, each_pair and each are interchangeable, and most Ruby developers default to each out of habit. Choosing each_pair is mainly a stylistic signal to the reader that the block will destructure the key-value pair explicitly. Neither method builds a new collection; both are about side effects like printing or logging.
.each_with_object
The .each_with_object method differs significantly from .each and .each_pair. It takes an object as an argument and yields that object along with each key-value pair. The object persists across iterations and is returned at the end. This makes it useful for accumulating results without explicitly tracking external variables.
numbers = { a: 1, b: 2, c: 3, d: 4 }
sum = numbers.each_with_object(0) do |(key, value), accumulator|
accumulator + value
end
puts sum # => 10
Notice the destructuring syntax — you can unpack the key-value pair directly in the block parameters. The double parentheses around (key, value) tell Ruby to destructure the two-element array that each_with_object yields before passing it to the block. Without those parentheses, you would receive a single array argument and need to index into it manually. The accumulator object is always the second block parameter, and you return it implicitly by mutating it inside the block.
You can build arrays, hashes, or any object:
words = { first: "hello", second: "world", third: "ruby" }
uppercased = words.each_with_object({}) do |(key, value), result|
result[key] = value.upcase
end
# => { first: "HELLO", second: "WORLD", third: "RUBY" }
Choosing the right method
Use .each or .each_pair when you need to:
- Perform side effects (printing, logging)
- Chain methods on the hash itself
- Iterate without needing to accumulate a result
Use .each_with_object when you need to:
- Build a new data structure from the hash
- Avoid explicit variable mutation outside the block
- Create transformations in a functional style
Ruby version notes
All three methods are available in Ruby 1.8 and later. The destructuring syntax requires Ruby 2.7 or later. Ruby 3.x maintains full backward compatibility.
See Also
- hash-dig — Safely retrieve nested values
- hash-fetch — Return a value by key with a configurable default for missing keys