Interesting Abuse (?) of Perl Modules
We start with this minimal Perl program.
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use lib '/home/jacoby/lib';
use LogMe;
sleep 60;
Sleep is built-in, so, what does LogMe
do?
package LogMe;
use strict;
use warnings;
use utf8;
use feature qw{ postderef say signatures state };
no warnings qw{ experimental::postderef experimental::signatures };
use Log::Log4perl;
use UUID::Tiny ':std';
my $uuid;
BEGIN {
$uuid = create_uuid_as_string( UUID_TIME, time );
my $status = qq{LogMe Begin: $uuid };
Log::Log4perl::init('/home/jacoby/.log4perl.conf');
my $logger = Log::Log4perl::get_logger('jacoby.logme');
$logger->info( 'INFO: ' . $status );
}
END {
my $status = qq{LogMe End: $uuid };
Log::Log4perl::init('/home/jacoby/.log4perl.conf');
my $logger = Log::Log4perl::get_logger('jacoby.logme');
$logger->info( 'INFO: ' . $status );
}
1
__DATA__
The UUIDs here are so I can connect the Begins and Ends in the log.
And the conf
log4perl.logger.jacoby.logme = INFO, Appender2
log4perl.appender.Appender2 = Log::Log4perl::Appender::File
log4perl.appender.Appender2.filename = /home/jacoby/.logme.log
log4perl.appender.Appender2.layout = PatternLayout
log4perl.appender.Appender2.layout.ConversionPattern=%d-%p-%H-%m%n
So the log looks like
2019/05/22 11:55:28-INFO-oz-INFO: LogMe Begin: 04e6fe41-7caa-11e9-b51b-f8899d319d10
2019/05/22 11:56:28-INFO-oz-INFO: LogMe End: 04e6fe41-7caa-11e9-b51b-f8899d319d10
The LogMe
module is less a module than a trojan horse smuggling BEGIN
and END
blocks. In this case, those blocks use Log::Log4perl
to indicate that the program that uses them starts and finishes.
(More on BEGIN
and END
blocks)
I wrote this a while ago, and I vaguely recall the point being to have a quick-and-easy way to tell which programs in my code base are used, how often, so I can judge which programs are worth the time to understand and refactor.
This, as is, does not do that. You’d want to use Cwd qw{abs_path}
and $caller = abs_path( $ENV{_} )
for that. If I had figured this out before, I likely would’ve used it already, instead of leaving it abandoned for months.
I like this idea. I think it’s clever. But there is something about a module that just gets use MyModule
without explicitly being told to do something that gives me willies.
Additionally, this sort of thing can be added to any other module.
This use case — knowing what programs you’re actually using — this is acceptable to me, but this is not the reason for BEGIN
and END
blocks so this should be counted as abuse, not use. But it works.
Is this less creepy than I think it is? Would you use this? Why?
If you have any questions or comments, I would be glad to hear it. Ask me on Twitter or make an issue on my blog repo.