Skip to content

Instantly share code, notes, and snippets.

@roryokane
Created July 31, 2012 19:56
Show Gist options
  • Save roryokane/3219977 to your computer and use it in GitHub Desktop.
Save roryokane/3219977 to your computer and use it in GitHub Desktop.
Hash#fetch_recursively for Ruby
# encoding: utf-8
# examples:
nested_hashes = {:a=>{:b=>{:c=>{:more=>"answer"}}}, :num=>42}
path = [:a, :b, :c, :more]
nested_hashes.fetch_recursively(path) #=> "answer"
nested_hashes.fetch_recursively([:num]) #=> 42
# wrong:
nested_hashes.fetch_recursively(:a) # raises NoMethodError; should pass an Array
nested_hashes.fetch_recursively([:num, :something]) # raises NoMethodError; can’t fetch from 42
nested_hashes.fetch_recursively([:a, :nosuch]) # raises KeyError; the hash in :a doesn’t have key :nosuch
# encoding: utf-8
class Hash
# fetches the first key from this hash, then the next key from that resulting hash, etc.
# for navigating nested hashes in an alternative way – `hash.fetch_recursively [1, 2, 3]` instead of `hash[1][2][3]`.
# raises a KeyError if any of the keys don’t exist in their hashes
# raises a NoMethodError if any of the interstitial values don’t respond to :fetch
def fetch_recursively(path)
path.inject(self, :fetch)
# “inject” rather than “reduce” because it’s really self that is being reduced down more than path. I am injecting the path into self to get a changed self.
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment