Skip to content

Instantly share code, notes, and snippets.

@stevenharman
Last active July 7, 2021 14:36
Show Gist options
  • Save stevenharman/5664318 to your computer and use it in GitHub Desktop.
Save stevenharman/5664318 to your computer and use it in GitHub Desktop.
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
@saraid
Copy link

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
Copy link

Good info.

@arvindvyas
Copy link

💯

@theasteve
Copy link

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

@stevenharman
Copy link
Author

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
Copy link

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