Today is for most sensible people the last working day of the year before Christmas. It's a time to relax and be merry, so I won't bother you with the gritty details of any serious module, I'll instead bring you tales of yore from the depths of the Acme:: namespace.
If you've been paying attention the last few years you'll know that the Acme:: namespace is the black sheep of the CPAN collective, featuring modules that don't really have any practical purpose, other than to show some funky features of the language.
Are we sitting comfortably? Then I shall begin.
A long time ago (in a galaxy, far far away) - or on the 1987 if
In this time what people want from the language has changed. For example, It used to be commonplace to use variables as soon as you wanted without declaring them first:
$number = 42 * 4077 * 1701; print $numer;
Of course, people soon got tired of making typos like the one above and
decided that we should have the strict
pragma. Amongst other things
this enforces that you declare things before you use them. Like so:
my $number = 42 * 4077 * 1701; print $numer; # causes an error
This explodes with a handy error telling us that $numer
hasn't been
predeclare (indeed, if you use diagnostics
as we've seen previously
you'll get a full explanation. This way perl doesn't silently create new
variables whenever you make a typo (and hence produce hard to track down
bugs) but complains right where the error is in your code there and then.
People moaned. use strict
allowed them to check what they were typing
was correct, but also prevented them from abusing many of Perl's more
powerful features. The argument goes that if you know what you're doing
then you don't need to use strict. The counter argument goes that you
should know when to turn it off.
no strict;
People claimed it was against the nature of the language to have to
turn these things off. Other people insisted that you use
strict
at the start of the program.
And then people would make
use strict
was
not to be used. And other people countered with modules that turned
In short, it got out of hand.
So eventually, whilst adding to the collection of goofball modules
declared under the Acme::
namespace some bright spark came up
with the idea of
INIT{unless(exists$INC{'strict.pm'}){unlink((caller)[1])}}
This says, when someone loads the module unless someone has used use
strict (i.e. it's been included in the %INC
hash off all loaded
modules) delete the file that contained the code that called us. Yes,
that's right. This module deletes your source code! No recommended
for commercial use!
This makes use of two handy, yet not widely abused, functions of Perl.
First, it looks in the %INC
hash. The %INC
hash contains
the full path to all the modules that we've created (in Unix notation,
no matter what platform.) For example:
#!/usr/bin/perl
# turn on perl's safety features use strict; use warnings;
use Data::Dumper; print Dumper \%INC;
prints out:
$VAR1 = { 'warnings/register.pm' => '/usr/share/perl/5.8.0/warnings/register.pm', 'bytes.pm' => '/usr/share/perl/5.8.0/bytes.pm', 'XSLoader.pm' => '/usr/lib/perl/5.8.0/XSLoader.pm', 'Carp.pm' => '/usr/share/perl/5.8.0/Carp.pm', 'Exporter.pm' => '/usr/share/perl/5.8.0/Exporter.pm', 'strict.pm' => '/usr/share/perl/5.8.0/strict.pm', 'warnings.pm' => '/usr/share/perl/5.8.0/warnings.pm', 'overload.pm' => '/usr/share/perl/5.8.0/overload.pm', 'Data/Dumper.pm' => '/usr/lib/perl/5.8.0/Data/Dumper.pm' };
The Acme::Code::Police module uses this hash to determine if you've loaded strict at any point in your code or not.
The other feature that Acme::Code::Police uses is the caller
function. This can be used to find out various details about the
code that called the current routine. For example:
#!/usr/bin/perl
# turn on perl's safety features use strict; use warnings;
sub foo { bar(); }
sub bar { print join ',', caller; }
foo();
This prints out:
main, myscript.pl, 7
Which is the package, filepath, and linenumber of what called bar
.
Acme::Code::Police uses this to work out the path to the file that
called Acme::Code::Police without calling use strict
first and
deleted it.
Acme::Code::FreedomFighter is a module that's designed to combat the nasty effects of Acme::Code::Police. Looking at the source of this module would make it immediately obvious how this functions, except for the fact that the author has used
Instead you'll have to guess what the source does, but I can tell you the effect. If you load it before Acme::Code::Police from your code then it's not the code that calls Acme::Code::Police that's getting deleted...but I'm not saying what else will