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