module KeyTree::Refine::DeepHash
Refinements
to Hash for deep_ methods, for traversing nested structures
Public Instance Methods
deep → Enumerator
click to toggle source
Return a deep enumerator for all (key_path
, value
) pairs in a nested hash structure.
# File lib/key_tree/refine/deep_hash.rb, line 13 def deep Enumerator.new do |yielder| deep_enumerator(yielder) end end
deep_delete(key_path)
click to toggle source
Delete a leaf value in a nested hash structure
Raises KeyError if a prefix of the key_path
has a value.
# File lib/key_tree/refine/deep_hash.rb, line 63 def deep_delete(key_path) *prefix_path, last_key = key_path result = prefix_path.reduce(self) do |hash, key| result = hash.fetch(key, nil) next result if result.is_a?(Hash) raise KeyError, %(prefix has value: "#{key_path}") end result.delete(last_key) end
deep_enumerator(yielder, prefix = [])
click to toggle source
# File lib/key_tree/refine/deep_hash.rb, line 145 def deep_enumerator(yielder, prefix = []) each do |key, value| key_path = prefix + [key] yielder << [key_path, value] value.deep_enumerator(yielder, key_path) if value.is_a?(Hash) end end
deep_fetch(key_path) → value
click to toggle source
deep_fetch(key_path, default) → value || default
deep_fetch(key_path) { |key_path| block } → value || block
Fetch a leaf value from a nested hash structure
# File lib/key_tree/refine/deep_hash.rb, line 25 def deep_fetch(key_path, *default) catch do |ball| result = key_path.reduce(self) do |hash, key| throw ball unless hash.is_a?(Hash) hash.fetch(key) { throw ball } end return result unless result.is_a?(Hash) end return yield(key_path) if block_given? return default.first unless default.empty? raise KeyError, %(key path invalid: "#{key_path}") end
deep_key_pathify → Hash
click to toggle source
Comvert any keys containing a .
in a hash structure to nested hashes.
# File lib/key_tree/refine/deep_hash.rb, line 137 def deep_key_pathify each_with_object({}) do |(key, value), result| key_path = Path[key] value = value.deep_key_pathify if value.is_a?(Hash) result.deep_store(key_path, value) end end
deep_merge(other) → self
click to toggle source
deep_merge(other) { |key_path, lhs, rhs| } → self
Deeply merge nested hash structures
# File lib/key_tree/refine/deep_hash.rb, line 95 def deep_merge(other, prefix = [], &block) merge(other) do |key, lhs, rhs| key_path = prefix + [key] both_are_hashes = lhs.is_a?(Hash) && rhs.is_a?(Hash) next lhs.deep_merge(rhs, key_path, &block) if both_are_hashes next yield(key_path, lhs, rhs) unless block.nil? rhs end end
deep_merge!(other) → self
click to toggle source
deep_merge!(other) { |key_path, lhs, rhs| } → self
Deeply merge nested hash structures
# File lib/key_tree/refine/deep_hash.rb, line 79 def deep_merge!(other, prefix = [], &block) merge!(other) do |key, lhs, rhs| key_path = prefix + [key] both_are_hashes = lhs.is_a?(Hash) && rhs.is_a?(Hash) next lhs.deep_merge!(rhs, key_path, &block) if both_are_hashes next yield(key_path, lhs, rhs) unless block.nil? rhs end end
deep_store(key_path, new_value) → new_value
click to toggle source
Store a new value in a nested hash structure, expanding it if necessary.
Raises KeyError if a prefix of the key_path
has a value.
# File lib/key_tree/refine/deep_hash.rb, line 46 def deep_store(key_path, new_value) *prefix_path, last_key = key_path result = prefix_path.reduce(self) do |hash, key| result = hash.fetch(key) { hash[key] = {} } next result if result.is_a?(Hash) raise KeyError, %(prefix has value: "#{key_path}") end result[last_key] = new_value end
deep_transform_keys { |key| block }
click to toggle source
Transform keys in a nested hash structure
# File lib/key_tree/refine/deep_hash.rb, line 110 def deep_transform_keys(&block) result = transform_keys(&block) result.transform_values! do |value| next value unless value.is_a?(Hash) value.deep_transform_keys(&block) end end
deep_transform_keys! { |key| block }
click to toggle source
Transform keys in a nested hash structure
# File lib/key_tree/refine/deep_hash.rb, line 123 def deep_transform_keys!(&block) result = transform_keys!(&block) result.transform_values! do |value| next value unless value.is_a?(Hash) value.deep_transform_keys!(&block) end end