Suggest different variables to use if we want to tunnel both v4 and v6
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / lib / puppet / parser / functions / range.rb
1 #
2 # range.rb
3 #
4 # TODO(Krzysztof Wilczynski): We probably need to approach numeric values differently ...
5 module Puppet::Parser::Functions
6   newfunction(:range, :type => :rvalue, :doc => <<-DOC
7     When given range in the form of (start, stop) it will extrapolate a range as
8     an array.
9
10     *Examples:*
11
12         range("0", "9")
13
14     Will return: [0,1,2,3,4,5,6,7,8,9]
15
16         range("00", "09")
17
18     Will return: [0,1,2,3,4,5,6,7,8,9] (Zero padded strings are converted to
19     integers automatically)
20
21         range("a", "c")
22
23     Will return: ["a","b","c"]
24
25         range("host01", "host10")
26     Will return: ["host01", "host02", ..., "host09", "host10"]
27     NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail.
28
29     Passing a third argument will cause the generated range to step by that
30     interval, e.g.
31
32         range("0", "9", "2")
33
34     Will return: [0,2,4,6,8]
35
36     The Puppet Language support Integer and Float ranges by using the type system. Those are suitable for
37     iterating a given number of times. Also see the step() function in Puppet for skipping values.
38
39         Integer[0, 9].each |$x| { notice($x) } # notices 0, 1, 2, ... 9
40     DOC
41              ) do |arguments|
42
43     raise(Puppet::ParseError, 'range(): Wrong number of arguments given (0 for 1)') if arguments.empty?
44
45     if arguments.size > 1
46       start = arguments[0]
47       stop  = arguments[1]
48       step  = arguments[2].nil? ? 1 : arguments[2].to_i.abs
49
50       type = '..' # Use the simplest type of Range available in Ruby
51
52     else # arguments.size == 1
53       value = arguments[0]
54
55       m = value.match(%r{^(\w+)(\.\.\.?|\-)(\w+)$})
56       if m
57         start = m[1]
58         stop  = m[3]
59
60         type = m[2]
61         step = 1
62       elsif value =~ %r{^.+$}
63         raise(Puppet::ParseError, "range(): Unable to compute range from the value: #{value}")
64       else
65         raise(Puppet::ParseError, "range(): Unknown range format: #{value}")
66       end
67     end
68
69     # If we were given an integer, ensure we work with one
70     if start.to_s =~ %r{^\d+$}
71       start = start.to_i
72       stop  = stop.to_i
73     else
74       start = start.to_s
75       stop  = stop.to_s
76     end
77
78     range = case type
79             when %r{^(..|-)$} then (start..stop)
80             when '...' then (start...stop) # Exclusive of last element
81             end
82
83     result = range.step(step).to_a
84
85     return result
86   end
87 end
88
89 # vim: set ts=2 sw=2 et :