Next: , Previous: Calling A Function, Up: Function Caveats


9.2.3.2 Controlling Variable Scope

There is no way to make a variable local to a { ... } block in awk, but you can make a variable local to a function. It is good practice to do so whenever a variable is needed only in that function.

To make a variable local to a function, simply declare the variable as an argument after the actual function arguments (see Definition Syntax). Look at the following example where variable i is a global variable used by both functions foo() and bar():

     function bar()
     {
         for (i = 0; i < 3; i++)
             print "bar's i=" i
     }
     
     function foo(j)
     {
         i = j + 1
         print "foo's i=" i
         bar()
         print "foo's i=" i
     }
     
     BEGIN {
           i = 10
           print "top's i=" i
           foo(0)
           print "top's i=" i
     }

Running this script produces the following, because the i in functions foo() and bar() and at the top level refer to the same variable instance:

     top's i=10
     foo's i=1
     bar's i=0
     bar's i=1
     bar's i=2
     foo's i=3
     top's i=3

If you want i to be local to both foo() and bar() do as follows (the extra-space before i is a coding convention to indicate that i is a local variable, not an argument):

     function bar(    i)
     {
         for (i = 0; i < 3; i++)
             print "bar's i=" i
     }
     
     function foo(j,    i)
     {
         i = j + 1
         print "foo's i=" i
         bar()
         print "foo's i=" i
     }
     
     BEGIN {
           i = 10
           print "top's i=" i
           foo(0)
           print "top's i=" i
     }

Running the corrected script produces the following:

     top's i=10
     foo's i=1
     bar's i=0
     bar's i=1
     bar's i=2
     foo's i=1
     top's i=10

Besides scalar values (strings and numbers), you may also have local arrays. By using a parameter name as an array, awk treats it as an array, and it is local to the function. In addition, recursive calls create new arrays. Consider this example:

     function some_func(p1,      a)
     {
         if (p1++ > 3)
             return
     
         a[p1] = p1
     
         some_func(p1)
     
         printf("At level %d, index %d %s found in a\n",
              p1, (p1 - 1), (p1 - 1) in a ? "is" : "is not")
         printf("At level %d, index %d %s found in a\n",
              p1, p1, p1 in a ? "is" : "is not")
         print ""
     }
     
     BEGIN {
         some_func(1)
     }

When run, this program produces the following output:

     At level 4, index 3 is not found in a
     At level 4, index 4 is found in a
     
     At level 3, index 2 is not found in a
     At level 3, index 3 is found in a
     
     At level 2, index 1 is not found in a
     At level 2, index 2 is found in a