Class: Puppet::Parser::AST::ArithmeticOperator

Inherits:
Branch show all
Defined in:
lib/puppet/parser/ast/arithmetic_operator.rb

Direct Known Subclasses

ArithmeticOperator2

Instance Attribute Summary collapse

Attributes inherited from Branch

#children, #pin

Instance Method Summary collapse

Constructor Details

#initialize(hash) ⇒ ArithmeticOperator

Returns a new instance of ArithmeticOperator.

Raises:

  • (ArgumentError)


77
78
79
80
81
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 77

def initialize(hash)
  super

  raise ArgumentError, "Invalid arithmetic operator #{@operator}" unless %w{+ - * / % << >>}.include?(@operator)
end

Instance Attribute Details

#lvalObject



7
8
9
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 7

def lval
  @lval
end

#operatorObject



7
8
9
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 7

def operator
  @operator
end

#rvalObject



7
8
9
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 7

def rval
  @rval
end

Instance Method Details

#assert_concatenation_supportedObject

Raises:



72
73
74
75
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 72

def assert_concatenation_supported
  return if Puppet[:parser] == 'future'
  raise ParseError.new("Unsupported Operation: Array concatenation available with '--parser future' setting only.")
end

#eachObject

Iterate across all of our children.



10
11
12
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 10

def each
  [@lval,@rval,@operator].each { |child| yield child }
end

#eval_array(left, right) ⇒ Object

Concatenates (+) two arrays, or appends (<<) any object to a newly created array.

Raises:

  • (ArgumentError)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 35

def eval_array(left, right)
  assert_concatenation_supported()

  raise ArgumentError, "operator #{@operator} is not applicable when one of the operands is an Array." unless %w{+ <<}.include?(@operator)
  raise ArgumentError, "left operand of #{@operator} must be an Array" unless left.is_a?(Array)
  if @operator == '+'
    raise ArgumentError, "right operand of #{@operator} must be an Array when left is an Array." unless right.is_a?(Array)
    return left + right
  end
  # only append case remains, left asserted to be an array, and right may be any object
  # wrapping right in an array and adding it ensures a new copy (operator << mutates).
  #
  left + [right]
end

#eval_hash(left, right) ⇒ Object

Merges two hashes.

Raises:

  • (ArgumentError)


52
53
54
55
56
57
58
59
60
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 52

def eval_hash(left, right)
  assert_concatenation_supported()

  raise ArgumentError, "operator #{@operator} is not applicable when one of the operands is an Hash." unless @operator == '+'
  raise ArgumentError, "left operand of #{@operator} must be an Hash" unless left.is_a?(Hash)
  raise ArgumentError, "right operand of #{@operator} must be an Hash" unless right.is_a?(Hash)
  # merge produces a merged copy
  left.merge(right)
end

#eval_numeric(left, right) ⇒ Object

Raises:

  • (ArgumentError)


62
63
64
65
66
67
68
69
70
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 62

def eval_numeric(left, right)
  left = Puppet::Parser::Scope.number?(left)
  right = Puppet::Parser::Scope.number?(right)
  raise ArgumentError, "left operand of #{@operator} is not a number" unless left != nil
  raise ArgumentError, "right operand of #{@operator} is not a number" unless right != nil

  # compute result
  left.send(@operator, right)
end

#evaluate(scope) ⇒ Object

Produces an object which is the result of the applying the operator to the of lval and rval operands.

  • Supports +, -, *, /, %, and <<, >> on numeric strings.

  • Supports + on arrays (concatenate), and hashes (merge)

  • Supports << on arrays (append)



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/puppet/parser/ast/arithmetic_operator.rb', line 19

def evaluate(scope)
  # evaluate the operands, should return a boolean value
  left = @lval.safeevaluate(scope)
  right = @rval.safeevaluate(scope)

  if left.is_a?(Array) || right.is_a?(Array)
    eval_array(left, right)
  elsif left.is_a?(Hash) || right.is_a?(Hash)
    eval_hash(left, right)
  else
    eval_numeric(left, right)
  end
end