Module: Collapsium::RecursiveFetch

Extended by:
ViralCapabilities
Included in:
UberHash
Defined in:
lib/collapsium/recursive_fetch.rb

Overview

Provides recursive (deep) fetch function for hashes.

Constant Summary

Constants included from ViralCapabilities

ViralCapabilities::DEFAULT_ANCESTORS, ViralCapabilities::ENHANCED_MARKER, ViralCapabilities::READ_METHODS, ViralCapabilities::WRITE_METHODS

Constants included from Support::Methods

Support::Methods::BUILTINS, Support::Methods::WRAPPER_HASH

Instance Method Summary collapse

Methods included from ViralCapabilities

call_virality, copy_mods, enhance, enhance_array_value, enhance_hash_value, enhance_value, extended, extended, included, included, prepended, prepended, set_ancestors

Methods included from Support::Methods

builtins, loop_detected?, repeated, #resolve_helpers, #wrap_method, wrappers

Instance Method Details

#recursive_fetch_all(key, default = nil, &block) ⇒ Object Also known as: recursive_fetch

Fetches all matching keys as an array, or the default value if no match was found. Blocks work as in ‘#recursive_fetch`



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/collapsium/recursive_fetch.rb', line 66

def recursive_fetch_all(key, default = nil, &block)
  result = []

  # Start simple at the top level.
  # rubocop:disable Lint/HandleExceptions
  begin
    ret = fetch(key, default)
    if ret != default
      if not block.nil?
        ret = yield self, ret, default
      end
      result << ret
    end
  rescue TypeError
    # Happens if self is an Array and key is a String that cannot
    # be converted to Integer.
  end
  # rubocop:enable Lint/HandleExceptions

  # We have to recurse for nested values
  result += map do |_, v|
    # If we have a Hash or Array, we need to recurse.
    if not (v.is_a? Hash or v.is_a? Array)
      next
    end

    enhanced = ViralCapabilities.enhance_value(self, v)
    inner = enhanced.recursive_fetch_all(key, default, &block)
    if inner != default
      next inner
    end
  end

  # Flatten and compact results to weed out non-matches
  result = result.flatten
  result.compact!

  if result.empty?
    return default
  end
  return result
end

#recursive_fetch_one(key, default = nil, &block) ⇒ Object

Fetches the first matching key, or the default value if no match was found. If a block is given, it is passed the value containing the key (the parent), the value at the key, and the default value in that order. Note: Be careful when using blocks: it’s return value becomes the match value. The typically correct behaviour is to return the match value passed to the block.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/collapsium/recursive_fetch.rb', line 28

def recursive_fetch_one(key, default = nil, &block)
  # Start simple at the top level.
  # rubocop:disable Lint/HandleExceptions
  begin
    result = fetch(key, default)
    if result != default
      if not block.nil?
        result = yield self, result, default
      end
      return result
    end
  rescue TypeError
    # Happens if self is an Array and key is a String that cannot
    # be converted to Integer.
  end
  # rubocop:enable Lint/HandleExceptions

  # We have to recurse for nested values
  result = map do |_, v|
    # If we have a Hash or Array, we need to recurse.
    if not (v.is_a? Hash or v.is_a? Array)
      next
    end

    enhanced = ViralCapabilities.enhance_value(self, v)
    inner = enhanced.recursive_fetch_one(key, default, &block)
    if inner != default
      next inner
    end
  end

  result.compact!
  return result[0] || default
end