78 lines
2.1 KiB
Ruby
78 lines
2.1 KiB
Ruby
|
module Puppet::Parser::Functions
|
||
|
newfunction(
|
||
|
:try_get_value,
|
||
|
:type => :rvalue,
|
||
|
:arity => -2,
|
||
|
:doc => <<-eos
|
||
|
Looks up into a complex structure of arrays and hashes and returns a value
|
||
|
or the default value if nothing was found.
|
||
|
|
||
|
Key can contain slashes to describe path components. The function will go down
|
||
|
the structure and try to extract the required value.
|
||
|
|
||
|
$data = {
|
||
|
'a' => {
|
||
|
'b' => [
|
||
|
'b1',
|
||
|
'b2',
|
||
|
'b3',
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$value = try_get_value($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.
|
||
|
/ -> (optional) path delimiter. Defaults to '/'.
|
||
|
|
||
|
In addition to the required "key" argument, "try_get_value" 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 |args|
|
||
|
path_lookup = lambda do |data, path, default|
|
||
|
debug "Try_get_value: #{path.inspect} from: #{data.inspect}"
|
||
|
if data.nil?
|
||
|
debug "Try_get_value: no data, return default: #{default.inspect}"
|
||
|
break default
|
||
|
end
|
||
|
unless path.is_a? Array
|
||
|
debug "Try_get_value: wrong path, return default: #{default.inspect}"
|
||
|
break default
|
||
|
end
|
||
|
unless path.any?
|
||
|
debug "Try_get_value: value found, return data: #{data.inspect}"
|
||
|
break data
|
||
|
end
|
||
|
unless data.is_a? Hash or data.is_a? Array
|
||
|
debug "Try_get_value: incorrect data, return default: #{default.inspect}"
|
||
|
break default
|
||
|
end
|
||
|
|
||
|
key = path.shift
|
||
|
if data.is_a? Array
|
||
|
begin
|
||
|
key = Integer key
|
||
|
rescue ArgumentError
|
||
|
debug "Try_get_value: non-numeric path for an array, return default: #{default.inspect}"
|
||
|
break default
|
||
|
end
|
||
|
end
|
||
|
path_lookup.call data[key], path, default
|
||
|
end
|
||
|
|
||
|
data = args[0]
|
||
|
path = args[1] || ''
|
||
|
default = args[2]
|
||
|
separator = args[3] || '/'
|
||
|
|
||
|
path = path.split separator
|
||
|
path_lookup.call data, path, default
|
||
|
end
|
||
|
end
|