Hash#fetch_values
Hash#fetch_values returns an array containing the values for the given keys. It behaves like values_at but differs in how it handles missing keys — it raises KeyError by default rather than returning nil, and it accepts an optional block for handling missing keys.
Basic Usage
h = { foo: 0, bar: 1, baz: 2 }
h.fetch_values(:baz, :foo)
# => [2, 0]
Unlike values_at, missing keys raise KeyError instead of returning nil:
h = { a: 1, b: 2 }
h.values_at(:a, :z)
# => [1, nil]
h.fetch_values(:a, :z)
# KeyError: key not found: :z
Signature
fetch_values(*keys) { |key| block }
Accepts one or more keys and returns an array of values in the same order. When a key is not found, raises KeyError unless a block is given.
Handling Missing Keys with a Block
Pass a block to provide a fallback value for missing keys:
h = { alice: 95, bob: 87 }
result = h.fetch_values(:alice, :carol) { |k| "unknown: #{k}" }
# => [95, "unknown: carol"]
The block is called only for keys that are not found. Keys that exist return their actual values.
h = { x: 10, y: 20 }
h.fetch_values(:x, :z) { |k| k.to_s.upcase }
# => [10, "Z"]
This makes fetch_values useful when you want different fallback behavior than nil but do not want to wrap every call in a begin/rescue block.
Comparison with values_at
| Method | Missing key behavior |
|---|---|
values_at(*keys) | Returns nil for missing keys |
fetch_values(*keys) | Raises KeyError |
| `fetch_values(*keys) { | k |
Use values_at when missing keys are expected and nil is acceptable. Use fetch_values when missing keys should be an error, or when you want to compute a fallback value inline with a block.
Real-World Example
Fetching specific fields from a configuration hash with a fallback:
config = {
host: "localhost",
port: 5432,
user: "app",
password: ENV["DB_PASSWORD"]
}
# Raise an error if required keys are missing
required = [:host, :port, :user, :password]
config.fetch_values(*required)
# KeyError if password env var is not set
With a block for optional keys:
optional = [:timeout, :pool_size, :ssl_mode]
config.fetch_values(:host, :port, *optional) { |k| nil }
# Returns values for host, port, and nil for missing optional keys
Chaining with Dig
Since fetch_values returns an array, you can chain array methods on the result:
scores = { alice: 95, bob: 87, carol: 92 }
scores.fetch_values(:alice, :bob, :carol).map(&:to_f)
# => [95.0, 87.0, 92.0]
See Also
- /reference/hash-methods/values/ — returns all values as an array
- /reference/hash-methods/fetch/ — fetch a single key with error handling
- /guides/ruby-hash-tricks/ — practical patterns for working with hashes