Module: Observed::Hash::KeyPathEncoding

Included in:
Builder, Fetcher
Defined in:
lib/observed/hash/key_path_encoding.rb

Instance Method Summary collapse

Instance Method Details

#at_key_path_on_hash(hash, key_path, options = {}) {|hash, key| ... } ⇒ Object

Decodes the key path such as ‘foo.bar’ to dig into the hash and returns ‘hash[:bar]`

Parameters:

  • hash (Hash)

    The hash to be dug

  • key_path (String)

    The key path which is consisted of one or more keys from the parent-to-child order, e.g. ‘foo.bar’ which is consisted of the keys ‘foo’ and ‘bar’ where the former is the key for the root hash and the latter if is the key for the nested hash in ‘{bar: ’the_value’}‘

  • options (Hash<Symbol,Boolean>) (defaults to: {})

Options Hash (options):

  • :create_if_missing (Boolean)

    when ‘true` the intermediate hash objects under the consisting keys in the key path is created automatically. In other words, you automatically get `foo:bar:{}` when the hash is `{}` and the key_path is `foo.bar.baz`

Yields:

  • yields the hash to be updated or read and the last key to reach the value at the specified key path

Yield Parameters:

  • hash (Hash)

    The hash which has the second to the last key in the key_path. e.g. ‘bar:1` where the input hash object is `foo:{bar:1}` and the key path is ’foo.bar’

  • key (String|Symbol)

    ‘bar’ in the example for the parameter ‘hash` immediately above.

Yield Returns:

  • (Object)

    The return value of this method is the return value of the given block



22
23
24
25
26
27
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
# File 'lib/observed/hash/key_path_encoding.rb', line 22

def at_key_path_on_hash(hash, key_path, options = {}, &block)
  create_if_missing = options[:create_if_missing]

  if create_if_missing.nil?
    fail "The key :create_if_missing must be exist in #{options}"
  end

  if hash.nil?
    fail 'The hash must not be nil'
  end

  first, *rest = case key_path
                 when Array
                   key_path
                 when String
                   key_path.split(".")
                 when Symbol
                   key_path
                 end
  key_str = first.to_s
  key_sym = first.intern
  key = if hash.key? key_str
          key_str
        else
          key_sym
        end
  if rest.empty?
    block.call hash, key
  else
    child = hash[key]
    if child
      at_key_path_on_hash(child, rest, options, &block)
    elsif create_if_missing
      hash[key] = created = {}
      at_key_path_on_hash(created, rest, options, &block)
    end
  end
end