#
# values_at.rb
#
-
module Puppet::Parser::Functions
- newfunction(:values_at, :type => :rvalue, :doc => <<-EOS
-Finds value inside an array based on location.
+ newfunction(:values_at, :type => :rvalue, :doc => <<-DOC
+ @summary
+ Finds value inside an array based on location.
+
+ The first argument is the array you want to analyze, and the second element can
+ be a combination of:
-The first argument is the array you want to analyze, and the second element can
-be a combination of:
+ * A single numeric index
+ * A range in the form of 'start-stop' (eg. 4-9)
+ * An array combining the above
-* A single numeric index
-* A range in the form of 'start-stop' (eg. 4-9)
-* An array combining the above
+ @return
+ an array of values identified by location
-*Examples*:
+ @example **Usage**
- values_at(['a','b','c'], 2)
+ values_at(['a','b','c'], 2)
+ Would return ['c']
-Would return ['c'].
+ values_at(['a','b','c'], ["0-1"])
+ Would return ['a','b']
- values_at(['a','b','c'], ["0-1"])
+ values_at(['a','b','c','d','e'], [0, "2-3"])
+ Would return ['a','c','d']
-Would return ['a','b'].
+ > *Note:*
+ Since Puppet 4.0.0 it is possible to slice an array with index and count directly in the language.
+ A negative value is taken to be "from the end" of the array:
- values_at(['a','b','c','d','e'], [0, "2-3"])
+ `['a', 'b', 'c', 'd'][1, 2]` results in `['b', 'c']`
+ `['a', 'b', 'c', 'd'][2, -1]` results in `['c', 'd']`
+ `['a', 'b', 'c', 'd'][1, -2]` results in `['b', 'c']`
-Would return ['a','c','d'].
- EOS
- ) do |arguments|
+ DOC
+ ) do |arguments|
raise(Puppet::ParseError, "values_at(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2
raise(Puppet::ParseError, 'values_at(): Requires array to work with')
end
- indices = [arguments.shift].flatten() # Get them all ... Pokemon ...
+ indices = [arguments.shift].flatten # Get them all ... Pokemon ...
- if not indices or indices.empty?
+ if !indices || indices.empty?
raise(Puppet::ParseError, 'values_at(): You must provide at least one positive index to collect')
end
- result = []
indices_list = []
indices.each do |i|
i = i.to_s
- if m = i.match(/^(\d+)(\.\.\.?|\-)(\d+)$/)
+ m = i.match(%r{^(\d+)(\.\.\.?|\-)(\d+)$})
+ if m
start = m[1].to_i
stop = m[3].to_i
type = m[2]
- if start > stop
- raise(Puppet::ParseError, 'values_at(): Stop index in given indices range is smaller than the start index')
- elsif stop > array.size - 1 # First element is at index 0 is it not?
- raise(Puppet::ParseError, 'values_at(): Stop index in given indices range exceeds array size')
- end
+ raise(Puppet::ParseError, 'values_at(): Stop index in given indices range is smaller than the start index') if start > stop
+ 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?
range = case type
- when /^(\.\.|\-)$/ then (start .. stop)
- when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ...
- end
+ when %r{^(\.\.|\-)$} then (start..stop)
+ when %r{^(\.\.\.)$} then (start...stop) # Exclusive of last element ...
+ end
- range.each { |i| indices_list << i.to_i }
+ range.each { |i| indices_list << i.to_i } # rubocop:disable Lint/ShadowingOuterLocalVariable : Value is meant to be shadowed
else
# Only positive numbers allowed in this case ...
- if not i.match(/^\d+$/)
+ unless i =~ %r{^\d+$}
raise(Puppet::ParseError, 'values_at(): Unknown format of given index')
end
end
# We remove nil values as they make no sense in Puppet DSL ...
- result = indices_list.collect { |i| array[i] }.compact
+ result = indices_list.map { |i| array[i] }.compact
return result
end