I just made a release of Test::Timer and it should be available on local your CPAN now.
The release is a maintenance release, with some internal clean-up. But it I am particularly satisfied with the changes in this release, so I want to share the details with you.
Test::Timer provides a test interface adhering to the Test Anything Protocol (TAP) and integrating with the existing test tool-chain for Perl, it relies on Benchmark, which is a older, but stable and quite popular benchmarking module.
The default output from Benchmark looks as follows:
2 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
This meant that earlier version of Test::Timer had to parse this string, in order to isolate data for use in the actual assertion part of the process.
Test::Timer hence implemented and nicely encapsulated this routine to do the parsing, using a regular-expression.
# helper method to change benchmmark's timestr to an integer
sub _timestring2time {
my $timestring = shift;
# $timestring:
# 2 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
my ($time) = $timestring =~ m/(\d+) /;
return $time;
}
Perl::Critic complained about the regular-expression not adhering to best practices for regular-expression.
This got me thinking. I love regular-expressions at the same time I know they can be error prone, hard to debug and in this case used for parsing output from a components beyond my control, meaning that the output could change without notice (meaning me not noticing). In this particular case I do not consider this a imminent risk, but still a risk.
Instead of spending time just adhering to the best practices for regular-expressions recommended by Perl::Critic, I decided to address the problem differently.
- The regular-expression changes would not address the parsing problem described above
- Benchmark had to offer more ways of excessing benchmark data or perhaps formatting the output
I read through the documentation and wrote up a small prototype.
First attempt was changes to the output format as offered by Benchmark, by altering the output from timestr
. This did however prove not to be as simple as I would prefer and it would still require parsing.
Then I discovered the set of accessors and real
seemed to be what I needed.
Here follows the final prototype:
#!/usr/bin/env perl
use strict;
use warnings;
use Benchmark;
my $t0 = Benchmark->new;
sleep(1);
my $t1 = Benchmark->new;
print timediff($t1, $t0)->real;
print "\n";
exit 0;
And the final solution ended up looking as follows:
my $timestring = timediff( $t1, $t0 )->real;
return $timestring;
From previously:
# parsing benchmark output
my $timestring = timestr( timediff( $t1, $t0 ) );
$time = _timestring2time($timestring);
return $time;
I ended up factoring out _timestring2time
and simply relying on Benchmark and learning some lessons:
- Read all the documentation
- Encapsulation is a savior
Next steps for following up on this is a complete encapsulation of the Benchmark object and evaluate using the "Dependency inversion principle".