class Puppet::Parser::AST::CollExpr

Attributes

form[RW]
oper[RW]
parens[RW]
test1[RW]
test2[RW]
type[RW]

Public Instance Methods

evaluate(scope) click to toggle source
# File lib/puppet/parser/ast/collexpr.rb, line 11
def evaluate(scope)
  if Puppet.future_parser?
    evaluate4x(scope)
  else
    evaluate3x(scope)
  end
end
evaluate3x(scope) click to toggle source

We return an object that does a late-binding evaluation.

# File lib/puppet/parser/ast/collexpr.rb, line 20
def evaluate3x(scope)
  # Make sure our contained expressions have all the info they need.
  [@test1, @test2].each do |t|
    if t.is_a?(self.class)
      t.form ||= self.form
      t.type ||= self.type
    end
  end

  # The code is only used for virtual lookups
  match1, code1 = @test1.safeevaluate scope
  match2, code2 = @test2.safeevaluate scope

  # First build up the virtual code.
  # If we're a conjunction operator, then we're calling code.  I did
  # some speed comparisons, and it's at least twice as fast doing these
  # case statements as doing an eval here.
  code = proc do |resource|
    case @oper
    when "and"; code1.call(resource) and code2.call(resource)
    when "or"; code1.call(resource) or code2.call(resource)
    when "=="
      if match1 == "tag"
        resource.tagged?(match2)
      else
        if resource[match1].is_a?(Array)
          resource[match1].include?(match2)
        else
          resource[match1] == match2
        end
      end
    when "!="; resource[match1] != match2
    end
  end

  match = [match1, @oper, match2]
  return match, code
end
evaluate4x(scope) click to toggle source

Late binding evaluation of a collect expression (as done in 3x), but with proper Puppet Language semantics for equals and include

# File lib/puppet/parser/ast/collexpr.rb, line 62
def evaluate4x(scope)
  # Make sure our contained expressions have all the info they need.
  [@test1, @test2].each do |t|
    if t.is_a?(self.class)
      t.form ||= self.form
      t.type ||= self.type
    end
  end

  # The code is only used for virtual lookups
  match1, code1 = @test1.safeevaluate scope
  match2, code2 = @test2.safeevaluate scope

  # First build up the virtual code.
  # If we're a conjunction operator, then we're calling code.  I did
  # some speed comparisons, and it's at least twice as fast doing these
  # case statements as doing an eval here.
  code = proc do |resource|
    case @oper
    when "and"; code1.call(resource) and code2.call(resource)
    when "or"; code1.call(resource) or code2.call(resource)
    when "=="
      if match1 == "tag"
        resource.tagged?(match2)
      else
        if resource[match1].is_a?(Array)
          @@compare_operator.include?(resource[match1], match2, scope)
        else
          @@compare_operator.equals(resource[match1], match2)
        end
      end
    when "!="; ! @@compare_operator.equals(resource[match1], match2)
    end
  end

  match = [match1, @oper, match2]
  return match, code
end

Public Class Methods

new(hash = {}) click to toggle source
# File lib/puppet/parser/ast/collexpr.rb, line 101
def initialize(hash = {})
  super
  if Puppet.future_parser?
    @@compare_operator ||= Puppet::Pops::Evaluator::CompareOperator.new
  end
  raise ArgumentError, "Invalid operator #{@oper}" unless %w{== != and or}.include?(@oper)
end