module Nuggets::Hash::DeepFetchMixin

Public Instance Methods

%(path, separator = '/')
Alias for: deep_fetch
deep_fetch(path[, separator]) → anObject click to toggle source
deep_fetch(path[, separator]) { |key| ... } → anObject

Recursively fetches keys in path, separated by separator if path is not an array, from hash. Maps each individual key according to the block if provided.

Examples:

hash = { 'foo' => { 'bar' => { 'baz' => 42 }, 'bay' => 23 } }
hash.deep_fetch('foo/bar/baz') #=> 42
hash.deep_fetch('foo/bar/bax') #=> nil
hash.deep_fetch('foo/bax/baz') #=> KeyError
hash.deep_fetch('foo/bay/baz') #=> TypeError
hash % 'foo/bar/baz' #=> 42
hash % %w[foo bar baz] #=> 42

hash = { foo: { bar: { baz: 42 } } }
hash.deep_fetch('foo/bar/baz', &:to_sym) #=> 42
hash % [:foo, :bar, :baz] #=> 42
   # File lib/nuggets/hash/deep_fetch_mixin.rb
52 def deep_fetch(path, separator = '/')
53   keys = path.is_a?(::Array) ? path : path.split(separator)
54   raise ::ArgumentError, 'no keys given' if keys.empty?
55 
56   hash, klass = self, self.class
57 
58   loop {
59     key = keys.shift
60     key = yield key if block_given?
61 
62     return hash[key] if keys.empty?
63 
64     unless (hash = hash.fetch(key)).is_a?(klass)
65       raise ::TypeError, '%p: %s expected, got %s' % [key, klass, hash.class]
66     end
67   }
68 end
Also aliased as: %