Hack #93. Return Active Values
Return values that automatically change as you use them.
The Contextual::Return module [Hack #92] has another very powerful trick up its sleeve. The scalar values it returns don't have to be constants; they can be "active." An active value is one that adapts itself each time it is evaluated. This is useful for performing initialization, cleanup, or error-handling code without forcing the caller to do anything special.
The Hack
For example, you can create a subroutine that returns a value that automatically tracks the elapsed time between events:
use Contextual::Return;
use Time::HiRes qw( sleep time ); # Allow subsecond timing
# Subroutine returns an active timer value...
sub timer
{
my $start = time; # Set initial start time
return VALUE # Return an active value that...
{
my $elapsed = time - $start; # 1. computes elapsed time
$start = time; # 2. resets start time
return $elapsed; # 3. returns elapsed time
}
}
# Create an active value...
my $process_timer = timer( );
# Use active value...
while (1)
{
do_some_long_process( );
print "Process took $process_timer seconds\\n";
}Because the timer( ) subroutine returns a contextual value that is computed within the VALUE block itself, that returned value becomes active. Each time the value of $process_timer is reevaluated (in the print statement), the value's VALUE block executes, recomputing and resetting the value stored in $process_timer.
Running the Hack
Of course, the real advantage here is that you ...