class Puppet::Parser::AST::Lambda

A block of statements/expressions with additional parameters Requires scope to contain the values for the defined parameters when evaluated If evaluated without a prepared scope, the lambda will behave like its super class.

Attributes

parameters[RW]

The lambda parameters. These are encoded as an array where each entry is an array of one or two object. The first is the parameter name, and the optional second object is the value expression (that will be evaluated when bound to a scope). The value expression is the default value for the parameter. All default values must be at the end of the parameter list.

@return [Array<Array<String,String>>] list of parameter names with optional value expression

Public Instance Methods

call(scope, *args) click to toggle source

Calls the lambda. Assigns argument values in a nested local scope that should be used to evaluate the lambda and then evaluates the lambda. @param scope [Puppet::Scope] the calling scope @return [Object] the result of evaluating the expression(s) in the lambda

# File lib/puppet/parser/ast/lambda.rb, line 37
def call(scope, *args)
  raise Puppet::ParseError, "Too many arguments: #{args.size} for #{parameters.size}" unless args.size <= parameters.size

  # associate values with parameters
  merged = parameters.zip(args)
  # calculate missing arguments
  missing = parameters.slice(args.size, parameters.size - args.size).select {|e| e.size == 1}
  unless missing.empty?
    optional = parameters.count { |p| p.size == 2 }
    raise Puppet::ParseError, "Too few arguments; #{args.size} for #{optional > 0 ? ' min ' : ''}#{parameters.size - optional}"
  end

  evaluated = merged.collect do |m|
    # m can be one of
    # m = [["name"], "given"]
    #   | [["name", default_expr], "given"]
    #
    # "given" is always an optional entry. If a parameter was provided then
    # the entry will be in the array, otherwise the m array will be a
    # single element.
    given_argument = m[1]
    argument_name = m[0][0]
    default_expression = m[0][1]

    value = if m.size == 1
      default_expression.safeevaluate(scope)
    else
      given_argument
    end
    [argument_name, value]
  end

  # Store the evaluated name => value associations in a new inner/local/ephemeral scope
  # (This is made complicated due to the fact that the implementation of scope is overloaded with
  # functionality and an inner ephemeral scope must be used (as opposed to just pushing a local scope
  # on a scope "stack").

  # Ensure variable exists with nil value if error occurs. 
  # Some ruby implementations does not like creating variable on return
  result = nil
  begin
    elevel = scope.ephemeral_level
    scope.ephemeral_from(Hash[evaluated], file, line)
    result = safeevaluate(scope)
  ensure
    scope.unset_ephemeral_var(elevel)
  end
  result
end
evaluate(scope) click to toggle source

Evaluates each expression/statement and produce the last expression evaluation result @return [Object] what the last expression evaluated to

# File lib/puppet/parser/ast/lambda.rb, line 21
def evaluate(scope)
  if @children.is_a? Puppet::Parser::AST::ASTArray
    result = nil
    @children.each {|expr| result = expr.evaluate(scope) }
    result
  else
    @children.evaluate(scope)
  end
end
optional_parameter_count() click to toggle source

Returns the number of optional parameters. @return [Integer] the number of optional accepted parameters

# File lib/puppet/parser/ast/lambda.rb, line 108
def optional_parameter_count
  @parameters.count {|p| p.size == 2 }
end
parameter_count() click to toggle source

Returns the number of parameters (required and optional) @return [Integer] the total number of accepted parameters

# File lib/puppet/parser/ast/lambda.rb, line 102
def parameter_count
  @parameters.size
end
parameter_names() click to toggle source
# File lib/puppet/parser/ast/lambda.rb, line 131
def parameter_names
  @parameters.collect {|p| p[0] }
end
puppet_lambda() click to toggle source

marker method checked with respond_to :#puppet_lambda

# File lib/puppet/parser/ast/lambda.rb, line 127
def puppet_lambda()
  true
end
to_s() click to toggle source
# File lib/puppet/parser/ast/lambda.rb, line 119
def to_s
  result = ["{|"]
  result += @parameters.collect {|p| "#{p[0]}" + (p.size == 2 && p[1]) ? p[1].to_s() : '' }.join(', ')
  result << "| ... }"
  result.join('')
end
validate() click to toggle source

Validates the lambda. Validation checks if parameters with default values are at the end of the list. (It is illegal to have a parameter with default value followed by one without).

@raise [Puppet::ParseError] if a parameter with a default comes before a parameter without default value

# File lib/puppet/parser/ast/lambda.rb, line 93
def validate
  params = parameters || []
  defaults = params.drop_while {|p| p.size < 2 }
  trailing = defaults.drop_while {|p| p.size == 2 }
  raise Puppet::ParseError, "Lambda parameters with default values must be placed last" unless trailing.empty?
end

Public Class Methods

new(options) click to toggle source
# File lib/puppet/parser/ast/lambda.rb, line 112
def initialize(options)
  super(options)
  # ensure there is an empty parameters structure if not given by creator
  @parameters = [] unless options[:parameters]
  validate
end