summaryrefslogtreecommitdiff
path: root/lib/puppet/parser/functions/dig.rb
blob: a9aa770df40e3d9a9dc33a02dd82994f704f810c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
#
# dig.rb
#

module Puppet::Parser::Functions
  newfunction(:dig, :type => :rvalue, :doc => <<-EOS
Looks up into a complex structure of arrays and hashes and returns nil
or the default value if nothing was found.

Path is an array of keys to be looked up in data argument. The function
will go down the structure and try to extract the required value.

$data = {
  'a' => {
    'b' => [
      'b1',
      'b2',
      'b3' ]}}

$value = dig($data, ['a', 'b', '2'], 'not_found')
=> $value = 'b3'

a -> first hash key
b -> second hash key
2 -> array index starting with 0

not_found -> (optional) will be returned if there is no value or the path
did not match. Defaults to nil.

In addition to the required "path" argument, "dig" accepts default
argument. It will be returned if no value was found or a path component is
missing. And the fourth argument can set a variable path separator.
    EOS
             ) do |arguments|
    # Two arguments are required
    raise(Puppet::ParseError, "dig(): Wrong number of arguments " +
                              "given (#{arguments.size} for at least 2)") if arguments.size < 2

    data, path, default = *arguments

    if !(data.is_a?(Hash) || data.is_a?(Array))
      raise(Puppet::ParseError, "dig(): first argument must be a hash or an array, " <<
                                "given #{data.class.name}")
    end

    unless path.is_a? Array
      raise(Puppet::ParseError, "dig(): second argument must be an array, " <<
                                "given #{path.class.name}")
    end

    value = path.reduce(data) { |h, k| (h.is_a?(Hash) || h.is_a?(Array)) ? h[k] : break }
    value.nil? ? default : value
  end
end