This class is the backing implementation of the Puppet function ‘lookup’. See puppet/parser/functions/lookup.rb for documentation.
This is the method called from the puppet/parser/functions/lookup.rb @param args [Array] array following the puppet function call conventions
# File lib/puppet/pops/binder/lookup.rb, line 159 def self.lookup(scope, args) type_calculator = Puppet::Pops::Types::TypeCalculator.new options = parse_lookup_args(args) validate_options(options, type_calculator) names = [options[:name]].flatten type = options[:type] result_with_name = names.reduce([]) do |memo, name| break memo if !memo[1].nil? [name, search_for(scope, type, name, options)] end result = if result_with_name[1].nil? # not found, use default (which may be nil), the default is already type checked options[:default] else # injector.lookup is type-safe already do no need to type check the result result_with_name[1] end # If a block is given it is called with :undef passed as 'nil' since the lookup function # is available from 3x with --binder turned on, and the evaluation is always 4x. # TODO PUPPET4: Simply pass the value # result = if pblock = options[:pblock] result2 = case pblock.parameter_count when 1 pblock.call(undef_as_nil(result)) when 2 pblock.call(result_with_name[ 0 ], undef_as_nil(result)) else pblock.call(result_with_name[ 0 ], undef_as_nil(result), undef_as_nil(options[ :default ])) end # if the given result was returned, there is no need to type-check it again if !result2.equal?(result) t = type_calculator.infer(undef_as_nil(result2)) if !type_calculator.assignable?(type, t) fail "the value produced by the given code block #{type_mismatch(type_calculator, type, t)}" end end result2 else result end # Finally, the result if nil must be acceptable or an error is raised if is_nil_or_undef?(result) && !options[:accept_undef] fail_lookup(names) else # Since the function may be used without future parser being in effect, nil is not handled in a good # way, and should instead be turned into :undef. # TODO PUPPET4: Simply return the result # Puppet.future_parser? ? result : nil_as_undef(result) end end
# File lib/puppet/pops/binder/lookup.rb, line 6 def self.parse_lookup_args(args) options = {} pblock = if args[-1].respond_to?(:puppet_lambda) args.pop end case args.size when 1 # name, or all options if args[ 0 ].is_a?(Hash) options = to_symbolic_hash(args[ 0 ]) else options[ :name ] = args[ 0 ] end when 2 # name and type, or name and options if args[ 1 ].is_a?(Hash) options = to_symbolic_hash(args[ 1 ]) options[:name] = args[ 0 ] # silently overwrite option with given name else options[:name] = args[ 0 ] options[:type] = args[ 1 ] end when 3 # name, type, default (no options) options[ :name ] = args[ 0 ] options[ :type ] = args[ 1 ] options[ :default ] = args[ 2 ] else raise Puppet::ParseError, "The lookup function accepts 1-3 arguments, got #{args.size}" end options[:pblock] = pblock options end