gawk: Assignment Ops
1
1 6.2.3 Assignment Expressions
1 ----------------------------
1
1 An "assignment" is an expression that stores a (usually different) value
1 into a variable. For example, let's assign the value one to the
1 variable 'z':
1
1 z = 1
1
1 After this expression is executed, the variable 'z' has the value
1 one. Whatever old value 'z' had before the assignment is forgotten.
1
1 Assignments can also store string values. For example, the following
1 stores the value '"this food is good"' in the variable 'message':
1
1 thing = "food"
1 predicate = "good"
1 message = "this " thing " is " predicate
1
1 This also illustrates string concatenation. The '=' sign is called an
1 "assignment operator". It is the simplest assignment operator because
1 the value of the righthand operand is stored unchanged. Most operators
1 (addition, concatenation, and so on) have no effect except to compute a
1 value. If the value isn't used, there's no reason to use the operator.
1 An assignment operator is different; it does produce a value, but even
1 if you ignore it, the assignment still makes itself felt through the
1 alteration of the variable. We call this a "side effect".
1
1 Variables::); it can also be a field (⇒Changing Fields) or an
1 array element (⇒Arrays). These are all called "lvalues", which
1 means they can appear on the lefthand side of an assignment operator.
1 The righthand operand may be any expression; it produces the new value
1 that the assignment stores in the specified variable, field, or array
1 element. (Such values are called "rvalues".)
1
1 It is important to note that variables do _not_ have permanent types.
1 A variable's type is simply the type of whatever value was last assigned
1 to it. In the following program fragment, the variable 'foo' has a
1 numeric value at first, and a string value later on:
1
1 foo = 1
1 print foo
1 foo = "bar"
1 print foo
1
1 When the second assignment gives 'foo' a string value, the fact that it
1 previously had a numeric value is forgotten.
1
1 String values that do not begin with a digit have a numeric value of
1 zero. After executing the following code, the value of 'foo' is five:
1
1 foo = "a string"
1 foo = foo + 5
1
1 NOTE: Using a variable as a number and then later as a string can
1 be confusing and is poor programming style. The previous two
1 examples illustrate how 'awk' works, _not_ how you should write
1 your programs!
1
1 An assignment is an expression, so it has a value--the same value
1 that is assigned. Thus, 'z = 1' is an expression with the value one.
1 One consequence of this is that you can write multiple assignments
1 together, such as:
1
1 x = y = z = 5
1
1 This example stores the value five in all three variables ('x', 'y', and
1 'z'). It does so because the value of 'z = 5', which is five, is stored
1 into 'y' and then the value of 'y = z = 5', which is five, is stored
1 into 'x'.
1
1 Assignments may be used anywhere an expression is called for. For
1 example, it is valid to write 'x != (y = 1)' to set 'y' to one, and then
1 test whether 'x' equals one. But this style tends to make programs hard
1 to read; such nesting of assignments should be avoided, except perhaps
1 in a one-shot program.
1
1 Aside from '=', there are several other assignment operators that do
1 arithmetic with the old value of the variable. For example, the
1 operator '+=' computes a new value by adding the righthand value to the
1 old value of the variable. Thus, the following assignment adds five to
1 the value of 'foo':
1
1 foo += 5
1
1 This is equivalent to the following:
1
1 foo = foo + 5
1
1 Use whichever makes the meaning of your program clearer.
1
1 There are situations where using '+=' (or any assignment operator) is
1 _not_ the same as simply repeating the lefthand operand in the righthand
1 expression. For example:
1
1 # Thanks to Pat Rankin for this example
1 BEGIN {
1 foo[rand()] += 5
1 for (x in foo)
1 print x, foo[x]
1
1 bar[rand()] = bar[rand()] + 5
1 for (x in bar)
1 print x, bar[x]
1 }
1
1 The indices of 'bar' are practically guaranteed to be different, because
1 'rand()' returns different values each time it is called. (Arrays and
1 the 'rand()' function haven't been covered yet. ⇒Arrays, and
1 ⇒Numeric Functions for more information.) This example
1 illustrates an important fact about assignment operators: the lefthand
1 expression is only evaluated _once_.
1
1 It is up to the implementation as to which expression is evaluated
1 first, the lefthand or the righthand. Consider this example:
1
1 i = 1
1 a[i += 2] = i + 1
1
1 The value of 'a[3]' could be either two or four.
1
1 ⇒Table 6.2 table-assign-ops. lists the arithmetic assignment
1 operators. In each case, the righthand operand is an expression whose
1 value is converted to a number.
1
1 Operator Effect
1 --------------------------------------------------------------------------
1 LVALUE '+=' Add INCREMENT to the value of LVALUE.
1 INCREMENT
1 LVALUE '-=' Subtract DECREMENT from the value of LVALUE.
1 DECREMENT
1 LVALUE '*=' Multiply the value of LVALUE by COEFFICIENT.
1 COEFFICIENT
1 LVALUE '/=' DIVISOR Divide the value of LVALUE by DIVISOR.
1 LVALUE '%=' MODULUS Set LVALUE to its remainder by MODULUS.
1 LVALUE '^=' POWER Raise LVALUE to the power POWER.
1 LVALUE '**=' POWER Raise LVALUE to the power POWER. (c.e.)
1
1 Table 6.2: Arithmetic assignment operators
1
1 NOTE: Only the '^=' operator is specified by POSIX. For maximum
1 portability, do not use the '**=' operator.
1
1 Syntactic Ambiguities Between '/=' and Regular Expressions
1
1 There is a syntactic ambiguity between the '/=' assignment operator
1 and regexp constants whose first character is an '='. (d.c.) This is
1 most notable in some commercial 'awk' versions. For example:
1
1 $ awk /==/ /dev/null
1 error-> awk: syntax error at source line 1
1 error-> context is
1 error-> >>> /= <<<
1 error-> awk: bailing out at source line 1
1
1 A workaround is:
1
1 awk '/[=]=/' /dev/null
1
1 'gawk' does not have this problem; BWK 'awk' and 'mawk' also do not.
1