While reading the source code for a module in the Ruby standard library, I came across the fetch
method on a Ruby Hash. Having used only the []
syntax so far, I was interested in learning why Ruby provides this alternate method that apparently does the same thing. Here’s a brief explanation of the Hash#fetch
method and when you should use it instead of the []
.
From the docs, the fetch
method returns the value for the given key, if found. Otherwise, it returns a KeyError
.
h = {foo: 0, bar: 1, baz: 2}
=> {:foo=>0, :bar=>1, :baz=>2}
h.fetch(:bar)
=> 1
h.fetch(:temp)
Traceback (most recent call last):
5: from /usr/local/opt/ruby/bin/irb:23:in `<main>'
4: from /usr/local/opt/ruby/bin/irb:23:in `load'
3: from /usr/local/Cellar/ruby/3.0.0_1/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
2: from (irb):38:in `<main>'
1: from (irb):38:in `fetch'
KeyError (key not found: :temp)
You can also specify a default value, if the key is missing.
h = {foo: 0, bar: 1, baz: 2}
h.fetch(:temp, 10)
=> 10
If key
is not found and a block is given, yield the key to the block and return the value returned by the block.
h.fetch(:temp) { |key| "No Key: #{key}" }
=> "No Key: temp"
In contrast to the fetch
method, the []
syntax will retrieve the value if the key
exists, otherwise, it returns nil
. These two lines of code are equivalent:
h = { foo: 10, bar: 20 }
h.fetch(:jam, 50)
=> 50
h[:jam] || 50
=> 50
As Jorg Mittag said in this answer on Stack Overflow,
With [], the creator of the hash controls what happens when a key doesn’t exist, with
fecth
you do.
Hope this was useful.