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

Good example

@salverde
Copy link

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

👍

@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