Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A subtle difference between Ruby's Hash.fetch(:key, :default) vs. (Hash[:key] || :default)
h = {
'a' => :a_value,
'b' => nil,
'c' => false
}
h.fetch('a', :default_value) #=> :a_value
h.fetch('b', :default_value) #=> nil
h.fetch('c', :default_value) #=> false
h.fetch('d', :default_value) #=> :default_value
(h['a'] || :default_value) #=> :a_value
(h['b'] || :default_value) #=> :default_value
(h['c'] || :default_value) #=> :default_value
(h['d'] || :default_value) #=> :default_value
@redex2000

This comment has been minimized.

Copy link

@redex2000 redex2000 commented May 14, 2016

Good example

@salsysd

This comment has been minimized.

Copy link

@salsysd salsysd commented Apr 11, 2017

#themoreyouknow


Is this difference only with MRI, what about JRuby, etc.? This company I'm working with deploys their ruby apps in production on Jruby, but we all develop locally on MRI, bitten me in the ass a few times. So just curious if you've discovered this difference between rubies/interpreter?

@marvin-min

This comment has been minimized.

Copy link

@marvin-min marvin-min commented May 15, 2017

👍

@saraid

This comment has been minimized.

Copy link

@saraid saraid commented Aug 1, 2017

For anyone who doesn't know, this is because Hash#fetch is interchangeable with hash.key?(key) ? hash[key] : default. I.e., #fetch checks for key existence, whereas || is testing for value falsiness. That's an extremely large distinction.

Note that {}[non_existent_key] still returns nil, but {}.fetch(non_existent_key) raises a KeyError.

@garrett-olson

This comment has been minimized.

Copy link

@garrett-olson garrett-olson commented Aug 21, 2017

Good info.

@arvindvyas

This comment has been minimized.

Copy link

@arvindvyas arvindvyas commented Aug 12, 2018

💯

@theasteve

This comment has been minimized.

Copy link

@theasteve theasteve commented Jan 17, 2019

Why use fetch if default value is not returned and nil can blow the application up? I'm now confused

@stevenharman

This comment has been minimized.

Copy link
Owner Author

@stevenharman stevenharman commented Jun 28, 2019

Why use fetch if default value is not returned and nil can blow the application up? I'm now confused

fetch does return a default value, presuming you provide one. You can also provide a block, the return value of which, will be used as the "default value" in the case the key is missing from the hash.

@gat-bryszard

This comment has been minimized.

Copy link

@gat-bryszard gat-bryszard commented Mar 24, 2021

You can get exactly same result if you do Hash.fetch(:key, ::default_value) || :default_value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment