module Puppet::Pops::Lookup::SubLookup
Constants
- SPECIAL
Public Instance Methods
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
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