Class: Puppet::Parser::AST::Lambda
- Inherits:
-
BlockExpression
- Object
- Branch
- BlockExpression
- Puppet::Parser::AST::Lambda
- Defined in:
- lib/puppet/parser/ast/lambda.rb
Overview
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.
Instance Attribute Summary collapse
-
#parameters ⇒ Array<Array<String,String>>
The lambda parameters.
Attributes inherited from Branch
Instance Method Summary collapse
-
#call(scope, *args) ⇒ Object
Calls the lambda.
-
#evaluate(scope) ⇒ Object
Evaluates each expression/statement and produce the last expression evaluation result.
-
#initialize(options) ⇒ Lambda
constructor
A new instance of Lambda.
-
#optional_parameter_count ⇒ Integer
Returns the number of optional parameters.
-
#parameter_count ⇒ Integer
Returns the number of parameters (required and optional).
- #parameter_names ⇒ Object
-
#puppet_lambda ⇒ Object
marker method checked with respond_to :puppet_lambda.
- #to_s ⇒ Object
-
#validate ⇒ Object
Validates the lambda.
Methods inherited from BlockExpression
Methods inherited from Branch
Constructor Details
#initialize(options) ⇒ Lambda
Returns a new instance of Lambda.
112 113 114 115 116 117 |
# File 'lib/puppet/parser/ast/lambda.rb', line 112 def initialize() super() # ensure there is an empty parameters structure if not given by creator @parameters = [] unless [:parameters] validate end |
Instance Attribute Details
#parameters ⇒ Array<Array<String,String>>
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.
18 19 20 |
# File 'lib/puppet/parser/ast/lambda.rb', line 18 def parameters @parameters end |
Instance Method Details
#call(scope, *args) ⇒ Object
Calls the lambda. Assigns argument values in a nested local scope that should be used to evaluate the lambda and then evaluates the lambda.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# 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) ⇒ Object
Evaluates each expression/statement and produce the last expression evaluation result
21 22 23 24 25 26 27 28 29 |
# 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 ⇒ Integer
Returns the number of optional parameters.
108 109 110 |
# File 'lib/puppet/parser/ast/lambda.rb', line 108 def optional_parameter_count @parameters.count {|p| p.size == 2 } end |
#parameter_count ⇒ Integer
Returns the number of parameters (required and optional)
102 103 104 |
# File 'lib/puppet/parser/ast/lambda.rb', line 102 def parameter_count @parameters.size end |
#parameter_names ⇒ Object
131 132 133 |
# File 'lib/puppet/parser/ast/lambda.rb', line 131 def parameter_names @parameters.collect {|p| p[0] } end |
#puppet_lambda ⇒ Object
marker method checked with respond_to :puppet_lambda
127 128 129 |
# File 'lib/puppet/parser/ast/lambda.rb', line 127 def puppet_lambda() true end |
#to_s ⇒ Object
119 120 121 122 123 124 |
# 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 ⇒ Object
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).
93 94 95 96 97 98 |
# 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 |