Next: , Previous: TransInt, Up: Getstats Internals



7.5 Function Internals

The functions hash maps commands to either a transformation (most likely a block of them), or Perl subroutines.

An example of function that is a block of transformations is "pdiff", which converts the "pdiff" column from the total number of seconds of CPU time used by every process on the system, into the percentage of CPU time used by non-measured processes.

     "procdiff" => ["ifexist", "procdiff",
     ["block",
             ["update", "procdiff",
               "if (\$procdiff) {
                return 100.0 *
                  eval(\"(\$procdiff - \$user - \$sys) / (\$procdiff)\")
               } else {
                return 0;
               }"],
             ["otherexec"],
             ["rename", "procdiff", "Excess CPU%"],
     ],
     [ "noop"]]

Notice that eval is used within the predicate, because pdiff may be zero. Before the string is evaluated, $pdiff could be replaced with zero, and if Perl sees a division by the constant zero it causes an error – even if that part of the expression is never evaluated. By using nested evals, we delay parsing of that expression until we have checked that $pdiff is not zero.

An example of a function that is a Perl subroutine is "set", which sets a variable that can be used for global replacement.

Set is invoked as ["set", "warn", "0"] (which sets the global replacement variable $warn to 0).

     "set" => sub {
     # The arguments to the function are the transformation itself
     # and the current relation that we are operating on.
     	my ($tref, $aref) = @_;
     # Make sure that we get the right number of arguments
             if ($#$tref > 2 || $#$tref <= 0) {
                     die "set takes only one or two argument.";
     } else {
     # Then do the bit of perl that we wanted.
                     if ($#$tref == 1) {
                             $globals{${$tref}[1]} = 1;
                     } else {
                             $globals{${$tref}[1]} = ${$tref}[2];
                     }
             }
     },

Because you can use arbitrarily complex functions, Getstats is arbitrarily extensible.