fetch vs. [] when working with hashes?

Ruby

Ruby Problem Overview


From Ruby Koans about_hashes.rb:

Why might you want to use #fetch instead of #[] when accessing hash keys?

Ruby Solutions


Solution 1 - Ruby

By default, using #[] will retrieve the hash value if it exists, and return nil if it doesn't exist *.

Using #fetch gives you a few options (see the docs on #fetch):

  • fetch(key_name): get the value if the key exists, raise a KeyError if it doesn't
  • fetch(key_name, default_value): get the value if the key exists, return default_value otherwise
  • fetch(key_name) { |key| "default" }: get the value if the key exists, otherwise run the supplied block and return the value.

Each one should be used as the situation requires, but #fetch is very feature-rich and can handle many cases depending on how it's used. For that reason I tend to prefer it over accessing keys with #[].

* As Marc-André Lafortune said, accessing a key with #[] will call #default_proc if it exists, or else return #default, which defaults to nil. See the doc entry for ::new for more information.

Solution 2 - Ruby

With [], the creator of the hash controls what happens when a key does not exist, with fetch you do.

Solution 3 - Ruby

fetch by default raises an error if the key is not found. You can supply a default value instead.

h = {}

h.fetch(:foo) # no default value, raises error
# => # ~> -:3:in `fetch': key not found: :foo (KeyError)

h.fetch(:bar, 10) # default value, returns default value
# => 10

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionaljabearView Question on Stackoverflow
Solution 1 - RubyJon CairnsView Answer on Stackoverflow
Solution 2 - RubyJörg W MittagView Answer on Stackoverflow
Solution 3 - RubySergio TulentsevView Answer on Stackoverflow