12.5.4 Closures That Share A Non-Scalar Variable

12.5.4  Closures That Share A Non-Scalar Variable

   We will now expand the set of closures we just presented so that non-scalar variables such as arrays, hashes or more complex structures can be shared by a set of closures. Once again, the closures are defined inside a subprogram. In the example that follows, the closures share an array variable.

 Program 12.20

sub counters{
    my @counters;
  
    sub returnCounter{
        my $counterNo = $_[0];
        $counters[$counterNo];
        }
    
    sub incrCounter{
        my $counterNo = $_[0];
        $counters[$counterNo]++
        }

    sub resetCounter{
        my $counterNo = $_[0];
        $counters[$counterNo] = 0;
    }

    sub resetCounters{
        @counters = ();
    }

    sub returnCounters{
        @counters;
    } 

    sub printCounters{
        printf "\@counters = %s\n", (join " ", @counters);
    }
}

 

Here, we have a set of closures that manipulate a variable local to the subprogram counters. The array variable @counters is not directly accessible from outside counters, but through the subprograms that are globally accessible, we have indirect access to the variable counters. The closures returnCounter, incrCounter and resetCounter each takes a number as a parameter and then returns the value, increments the value or resets the value, respectively. The closures resetCounters,
returnCounters and

printCounters do not take any actual parameter, and work on the whole array counters.

Below, we have some example calls of these closures. Of course, before we can call any of the closures, we need to call counters so that the variable counters and the subprograms that are defined inside counters are defined.

 

counters;

 

incrCounter(0);

printCounters;         #prints 1 0 0 0

 

incrCounter(1) ; incrCounter (2); incrCounter (3);

printCounters;         #prints 1 1 1 1

 

incrCounter (3); incrCounter (0); incrCounter (0);

printCounters;         #prints 3 1 1 2

 

resetCounter (2); incrCounter(2); incrCounter(0);

printCounters;         #prints 4 1 1 2

 

In summary, what we see here is that closures can be used to abstract data structures access to which is guarded through the use of subprograms specifically defined for the purpose.