module Puppet::Pops::Lookup::SubLookup

Constants

SPECIAL

Public Instance Methods

split_key(key) { |'Syntax error'| ... } click to toggle source

Split key into segments. A segment may be a quoted string (both single and double quotes can be used) and the segment separator is the '.' character. Whitespace will be trimmed off on both sides of each segment. Whitespace within quotes are not trimmed.

If the key cannot be parsed, this method will yield a string describing the problem to a one parameter block. The block must return an exception instance.

@param key [String] the string to split @return [Array<String>] the array of segments @yieldparam problem [String] the problem, i.e. 'Syntax error' @yieldreturn [Exception] the exception to raise

@api public

   # File lib/puppet/pops/lookup/sub_lookup.rb
20 def split_key(key)
21   return [key] if key.match(SPECIAL).nil?
22   segments = key.split(/(\s*"[^"]+"\s*|\s*'[^']+'\s*|[^'".]+)/)
23   if segments.empty?
24     # Only happens if the original key was an empty string
25     raise yield('Syntax error')
26   elsif segments.shift == ''
27     count = segments.size
28     raise yield('Syntax error') unless count > 0
29 
30     segments.keep_if { |seg| seg != '.' }
31     raise yield('Syntax error') unless segments.size * 2 == count + 1
32     segments.map! do |segment|
33       segment.strip!
34       if segment.start_with?('"', "'")
35         segment[1..-2]
36       elsif segment =~ /^(:?[+-]?[0-9]+)$/
37         segment.to_i
38       else
39         segment
40       end
41     end
42   else
43     raise yield('Syntax error')
44   end
45 end
sub_lookup(key, context, segments, value) click to toggle source

Perform a sub-lookup using the given segments to access the given value. Each segment must be a string. A string consisting entirely of digits will be treated as an indexed lookup which means that the value that it is applied to must be an array. Other types of segments will expect that the given value is something other than a String that implements the '#[]' method.

@param key [String] the original key (only used for error messages) @param context [Context] The current lookup context @param segments [Array<String>] the segments to use for lookup @param value [Object] the value to access using the segments @return [Object] the value obtained when accessing the value

@api public

   # File lib/puppet/pops/lookup/sub_lookup.rb
59 def sub_lookup(key, context, segments, value)
60   lookup_invocation = context.is_a?(Invocation) ? context : context.invocation
61   lookup_invocation.with(:sub_lookup, segments) do
62     segments.each do |segment|
63       lookup_invocation.with(:segment, segment) do
64         if value.nil?
65           lookup_invocation.report_not_found(segment)
66           throw :no_such_key
67         end
68         if segment.is_a?(Integer) && value.instance_of?(Array)
69           unless segment >= 0 && segment < value.size
70             lookup_invocation.report_not_found(segment)
71             throw :no_such_key
72           end
73         else
74           unless value.respond_to?(:'[]') && !(value.is_a?(Array) || value.instance_of?(String))
75             raise Puppet::DataBinding::LookupError,
76               _("Data Provider type mismatch: Got %{klass} when a hash-like object was expected to access value using '%{segment}' from key '%{key}'") %
77                 { klass: value.class.name, segment: segment, key: key }
78           end
79           unless value.include?(segment)
80             lookup_invocation.report_not_found(segment)
81             throw :no_such_key
82           end
83         end
84         value = value[segment]
85         lookup_invocation.report_found(segment, value)
86       end
87     end
88     value
89   end
90 end