Expressions and operators

are statements that resolve to values. You can use expressions almost anywhere a value is required. Expressions can be compounded with other expressions, and the entire combined expression resolves to a single value.

In the Puppet language, nearly everything is an expression, including literal values, references to variables, resource declarations, function calls, and more. In other words, almost all statements in the language resolve to a value and can be used anywhere that value would be expected.

Most of this page is about expressions that are constructed with . Operators take input values and operate on them (for example, mathematically) to result in some other value. Other kinds of expressions (for example, function calls) are described in more detail on other pages.

You can surround an expression by parentheses to control the order of evaluation in compound expressions (for example, 10+10/5 is 12, and (10+10)/5 is 4), or to make your code clearer.

For formal descriptions of expressions constructed with operators and other elements of the Puppet language, see the Puppet language specification.

Operator expressions

When you create compound expressions by using other expressions as operands, use parentheses for clarity and readability:

Order of operations

Compound expressions are evaluated in a standard order of operations. Expressions wrapped in parentheses are evaluated first, starting from the innermost expression:

# This example resolves to 30, not 23: notice( (7+8)*2 )
For the sake of clarity, use parentheses in all but the simplest compound expressions. The precedence of operators, from highest to lowest, is:
Precedence Operator
1 ! (unary: not)
2 - (unary: numeric negation)
3 * (unary: array splat)
4 in
5 =~ and !~ (regex or data type match or non-match)
6 * , / , % (multiplication, division, and modulo)
7 + and - (addition/array concatenation and subtraction/array deletion)
8 > (left shift and right shift)
9 == and != (equal and not equal)
10 >= , , and < (greater or equal, less or equal, greater than, and less than)
11 and
12 or
13 = (assignment)

Comparison operators

Comparison operators take operands of several data types, and resolve to Boolean values.

Comparisons of numbers convert the operands to and from floating point and integer values, such that 1.0 == 1 is true. However, keep in mind that floating point values created by division are inexact, so mathematically equal values can be slightly unequal when turned into floating point values.

You can compare any two values with equals == or not equals != , but only strings, numbers, and data types that require values to have a defined order can be compared with the less than or greater than operators.

Note: Comparisons of string values are case insensitive for characters in the US ASCII range. Characters outside this range are case sensitive.

Characters are compared based on their encoding. For characters in the US ASCII range, punctuation comes before digits, digits are in the order 0, 1, 2, . 9, and letters are in alphabetical order. For characters outside US ASCII, ordering is defined by their UTF-8 character code, which might not always place them in alphabetical order for a given locale.

== (equality)

!= (non-equality)

Resolves to false if the operands are equal. So, $x != $y is the same as !($x == $y) . It has the same behavior and restrictions, but opposite result, as equality == , above.

Resolves to true if the left operand is smaller than the right operand. Accepts numbers, strings, and data types; both operands must be the same type. When acting on data types, a less-than comparison is true if the left operand is a subset of the right operand.

> (greater than)

Resolves to true if the left operand is larger than the right operand. Accepts numbers, strings, and data types; both operands must be the same type. When acting on data types, a greater-than comparison is true if the left operand is a superset of the right operand.

Resolves to true if the left operand is smaller than or equal to the right operand. Accepts numbers, strings, and data types; both operands must be the same type. When acting on data types, a less-than-or-equal-to comparison is true if the left operand is the same as the right operand or is a subset of it.

>= (greater than or equal to)

Resolves to true if the left operand is larger than or equal to the right operand. Accepts numbers, strings, and data types; both operands must be the same type. When acting on data types, a greater-than-or-equal-to comparison is true if the left operand is the same as the right operand or is a superset of it.

=~ (regex or data type match)

Resolves to true if the left operand matches the right operand. Matching means different things, depending on what the right operand is.

If the right operand is a data type, the left operand can be any value. The expression resolves to true if the left operand has the specified data type. For example, 5 =~ Integer and 5 =~ Integer[1,10] are both true .

!~ (regex or data type non-match)

Resolves to false if the left operand matches the right operand. So, $x !~ $y is the same as !($x =~ $y) . It has the same behavior and restrictions, but opposite result, as regex match =~ , above.

in

Resolves to true if the right operand contains the left operand. The exact definition of "contains" here depends on the data type of the right operand. See table below.

Expression How in expression is evaluated
String in String Tests whether the left operand is a substring of the right, ignoring case:
'eat' in 'eaten' # resolves to true 'Eat' in 'eaten' # resolves to true
'eat' in ['eat', 'ate', 'eating'] # resolves to true 'Eat' in ['eat', 'ate', 'eating'] # resolves to true
'eat' in < 'eat' =>'present tense', 'ate' => 'past tense'> # resolves to true 'eat' in < 'present' =>'eat', 'past' => 'ate' > # resolves to false
# note the case-insensitive option ?i /(?i:EAT)/ in 'eatery' # resolves to true
/(?i:EAT)/ in ['eat', 'ate', 'eating'] # resolves to true
/(?i:EAT)/ in < 'eat' =>'present tense', 'ate' => 'past tense'> # resolves to true /(?i:EAT)/ in < 'present' =>'eat', 'past' => 'ate' > # resolves to false 
# looking for integers between 100 and 199 Integer[100, 199] in [1, 2, 125] # resolves to true Integer[100, 199] in [1, 2, 25] # resolves to false

Boolean operators

Boolean expressions resolve to boolean values. They are most useful when creating compound expressions.

A boolean operator takes boolean operands. If you pass in another type, it will be converted to boolean; see the section Automatic conversion to boolean in the data type documentation.

and

Resolves to true if both operands are true, otherwise resolves to false .

or

Resolves to true if either operand is true.

! (not)

Takes one operand. Resolves to true if the operand is false, and false if the operand is true.
$my_value = true notice ( !$my_value ) # Resolves to false

Arithmetic operators

Arithmetic expressions resolve to numeric values. Except for the unary negative - , arithmetic operators take two numeric operands. If an operand is a string, it's converted to numeric form. The operation fails if a string can't be converted.

+ (addition)

Resolves to the sum of the two operands.

- (subtraction and negation)

When used with two operands, resolves to the difference of the two operands, left minus right. When used with one operand, returns the value of subtracting that operand from zero.

/ (division)

Resolves to the quotient of the two operands, the left divided by the right.

* (multiplication)

Resolves to the product of the two operands. The asterisk is also used as a unary splat operator for arrays (see below).

% (modulo)

Resolves to the remainder of dividing the left operand by the right operand:
5 % 2 # resolves to 1 32 % 7 # resolves to 4

Left bitwise shift: shifts the left operand by the number of places specified by the right operand. This is equivalent to rounding both operands down to the nearest integer, and multiplying the left operand by 2 to the power of the right operand:

>> (right shift)

Right bitwise shift: shifts the left operand by the number of places specified by the right operand. This is equivalent to rounding each operand down to the nearest integer, and dividing the left operand by 2 to the power of the right operand:

Array operators

Array operators take arrays as operands, and, with the exception of * (unary splat), they resolve to array values.

* (splat)

For example:
$a = ['vim', 'emacs'] myfunc($a) # Calls myfunc with a single argument, the array containing 'vim' and 'emacs' : # myfunc(['vim','emacs']) myfunc(*$a) # Calls myfunc with two arguments, 'vim' and 'emacs': # myfunc('vim','emacs')
Another example:
$a = ['vim', 'emacs'] $x = 'vim' notice case $x < $a : < 'an array with both vim and emacs' >*$a : < 'vim or emacs' >default : < 'no match' >>

Resolves to an array containing the elements in the left operand, with the right operand as its final element.

The left operand must be an array, and the right operand can be any data type. Appending adds only a single element to an array. To add multiple elements from one array to another, use the concatenation operator + .

[1, 2, 3] 
The append operator does not change its operands; it creates a new value.

+ (concatenation)

Resolves to an array containing the elements in the left operand followed by the elements in the right operand.

Both operands must be arrays. If the left operand isn't an array, Puppet interprets + as arithmetic addition. If the right operand is a scalar value, it is converted to a single-element array first.

Hash values are converted to arrays instead of wrapped, so you must wrap them yourself.

[1, 2, 3] + 1 # resolves to [1, 2, 3, 1] [1, 2, 3] + [1] # resolves to [1, 2, 3, 1] [1, 2, 3] + [[1]] # resolves to [1, 2, 3, [1]]
The concatenation operator does not change its operands; it creates a new value.

- (removal)

Resolves to an array containing the elements in the left operand, with every occurrence of elements in the right operand removed.

Both operands must be arrays. If the left operand isn't an array, Puppet interprets - as arithmetic subtraction. If the right operand is a scalar value, it is converted to a single-element array first.

Hash values aren't automatically wrapped in arrays, so you must always wrap them yourself.

[1, 2, 3, 4, 5, 1, 1] - 1 # resolves to [2, 3, 4, 5] [1, 2, 3, 4, 5, 1, 1] - [1] # resolves to [2, 3, 4, 5] [1, 2, 3, [1, 2]] - [1, 2] # resolves to [3, [1, 2]] [1, 2, 3, [1, 2]] - [[1, 2]] # resolves to [1, 2, 3]
The removal operator does not change its operands; it creates a new value.

Hash operators

Hash operators accept hashes as their left operand, and hashes or specific kinds of arrays as their right operand. The expressions resolve to hash values.

+ (merging)

Resolves to a hash containing the keys and values in the left operand and the keys and values in the right operand. If a key is present in both operands, the final hash uses the value from the right. It does not merge hashes recursively; it only merges top-level keys.

 10, b => 20> + 30> # resolves to 10, b => 30> 10, b => 20> + 30> # resolves to 10, b => 30, c => 30> 10, b => 20> + [c, 30] # resolves to 10, b => 30, c => 30> 10, b => 20> + 30 # gives an error 10, b => 20> + [30] # gives an error
The merging operator does not change its operands; it creates a new value.

- (removal)

Resolves to a hash containing the keys and values in the left operand, minus any keys that are also present in the right operand.

 first, b => second, c => 17> - 17, a => "something else"> # resolves to second> first, b => second, c => 17> - a, d => d> # resolves to second, c => 17> first, b => second, c => 17> - [c, a] # resolves to second> first, b => second, c => 17> - c # resolves to first, b => second> 
The removal operator does not change its operands; it creates a new value.

Assignment operator

Puppet has one assignment operator, = .

= (assignment)

The assignment operator sets the variable on the left side to the value on the right side. The expression resolves to the value of the right hand side. Variables can be set only one time, after which, attempts to set the variable to a new value cause an error.