4 module Puppet::Parser::Functions
5 newfunction(:values_at, :type => :rvalue, :doc => <<-DOC
6 Finds value inside an array based on location.
8 The first argument is the array you want to analyze, and the second element can
11 * A single numeric index
12 * A range in the form of 'start-stop' (eg. 4-9)
13 * An array combining the above
17 values_at(['a','b','c'], 2)
21 values_at(['a','b','c'], ["0-1"])
23 Would return ['a','b'].
25 values_at(['a','b','c','d','e'], [0, "2-3"])
27 Would return ['a','c','d'].
29 Note that since Puppet 4.0.0 it is possible to slice an array with index and count directly in the language.
30 A negative value is taken to be "from the end" of the array:
32 ['a', 'b', 'c', 'd'][1, 2] # results in ['b', 'c']
33 ['a', 'b', 'c', 'd'][2, -1] # results in ['c', 'd']
34 ['a', 'b', 'c', 'd'][1, -2] # results in ['b', 'c']
38 raise(Puppet::ParseError, "values_at(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2
40 array = arguments.shift
42 unless array.is_a?(Array)
43 raise(Puppet::ParseError, 'values_at(): Requires array to work with')
46 indices = [arguments.shift].flatten # Get them all ... Pokemon ...
48 if !indices || indices.empty?
49 raise(Puppet::ParseError, 'values_at(): You must provide at least one positive index to collect')
56 m = i.match(%r{^(\d+)(\.\.\.?|\-)(\d+)$})
63 raise(Puppet::ParseError, 'values_at(): Stop index in given indices range is smaller than the start index') if start > stop
64 raise(Puppet::ParseError, 'values_at(): Stop index in given indices range exceeds array size') if stop > array.size - 1 # First element is at index 0 is it not?
67 when %r{^(\.\.|\-)$} then (start..stop)
68 when %r{^(\.\.\.)$} then (start...stop) # Exclusive of last element ...
71 range.each { |i| indices_list << i.to_i } # rubocop:disable Lint/ShadowingOuterLocalVariable : Value is meant to be shadowed
73 # Only positive numbers allowed in this case ...
75 raise(Puppet::ParseError, 'values_at(): Unknown format of given index')
78 # In Puppet numbers are often string-encoded ...
81 if i > array.size - 1 # Same story. First element is at index 0 ...
82 raise(Puppet::ParseError, 'values_at(): Given index exceeds array size')
89 # We remove nil values as they make no sense in Puppet DSL ...
90 result = indices_list.map { |i| array[i] }.compact
96 # vim: set ts=2 sw=2 et :