A few, fun Perl exercises
Trick or treat with funny Perl modules
One of the great strengths of the Perl community is CPAN, the Comprehensive Perl Archive Network. If you've written a module for Perl that might be useful to others, the community encourages you to release it on CPAN. Given that the Perl community also encourages experimentation and play, part of the CPAN namespace is reserved for modules that could be considered frivolous or trivial, the
Acme:: hierarchy. Some of these modules, while obviously fitting into the "frivolous or trivial" category, are excellent learning exercises. With Halloween coming up, let's take a look at four amusing Acme modules just for fun!
LookOfDisapproval module is a proof that you can implement subroutine names in Unicode in Perl. She created the subroutine
ಠ_ಠ (if this doesn't render correctly in your browser, see the image below), which behaves identically to Perl's
warn function. The source code is a mere 29 lines long, shorter by quite a bit than the documentation describing the module. This snippet of code shows how to use it:
ಠ_ಠ 'Tsk, tsk, tsk...';
The output looks like a conventional Perl warning:
Tsk, tsk, tsk... at test1.pl line 2.
You can find more documentation on the module and view the source code at Acme::LookOfDisapproval.
An algorithm for a loaded set of dice is not overly difficult to implement, but leave it to Jim Bacon to actually release it to open source! Cleverly,
Acme::Dice can roll dice and either return the sum of the set of dice, or the individual dice in the set, depending on how you call it. You can specify how many dice to roll, how many sides each die has (thus making it useful for role playing games) and if one value should be favored, how heavily it is favored. There's a routine in the module to roll craps, or two six-sided dice, with an optional bias toward rolling a 7.
Here's a little bit of code:
use Acme::Dice qw(roll_dice roll_craps);
# roll 3d10, honestly
my $total = roll_dice( dice => 3, sides => 10);
print "3d10: $total\n";
# roll 6d6, and weight 4 more heavily, returning the individual dice
my @dice = roll_dice( dice => 6, sides => 6, favor => 4, bias => 40 );
print '6d6: '.join('-', @dice)."\n";
# shoot craps, with loaded dice
my $craps_roll = roll_craps( bias => 30 );
print "Craps roll: $craps_roll\n";
And the output:
Craps roll: 7
Be careful with this module; Jim is sneaky, and even if you specify an honest set of dice...well, read the source code. It's not a bug. You can see this module's source code at Acme::Dice.
carp works like
warn, but also returns a call stack trace, which is useful for debugging problems involving module calls. With
carp you can see the thread of calls, and better understand where things went wrong. Damian Conway's
Acme::Crap lets you be a little more emphatic in your error messaging. Here's some code:
crap "we have a problem";
crap! "this is a bigger problem";
crap!! "this problem is pretty serious";
crap!!! "really, really bad things have happened";
...and the output:
we have a problem at test1.pl line 3.
This is a bigger problem! at test1.pl line 4.
This Problem Is Pretty Serious!! at test1.pl line 5.
REALLY, REALLY BAD THINGS HAVE HAPPENED!!! at test1.pl line 6.
As you can see, more exclamation points turn up the emphasis level of the message. You could, if you wanted to, use this as a way of differentiating between severity of warnings. Heaven alone knows why you might want to, but here is a way. Source code and slightly more documentation for this module are at Acme::Crap.
In Perl, objects are nothing more than data structures that have been blessed, or explicitly associated with a class. The
bless function is usually used in object constructors, but could just as easily be used to arbitrarily associate any properly-formed data structure as an object of a class. While
bless is built into Perl, there isn't a directive to do the reverse—to dissociate a data structure from a class, leaving the original structure intact. Enter Ian Brayshaw's
Acme::Damn, to give developers that capability, as little-used as it might be. Here's an abstract snippet to give you an idea:
# bunch of code here, that defines $ref
# $ref could be an arrayref, or a reference to a scalar, but most likely is a hashref
my $obj = bless $ref , 'My::Class';
# $obj is now an object instance of My::Class, and you can call methods on it.
my $new_ref = damn $obj; # unbless it!
# neither $new_ref nor $obj are My::Class objects at this point, and
# attempts to use methods from that class on either will result in an error
It's a bit esoteric, but I've actually seen
Acme::Damn used in unit test code. For this specific narrow circumstance it can be useful, as strange as it may seem. Code and documentation for this module are at Acme::Damn.
There are many thousands of Acme modules on CPAN. The
Acme:: namespace is often used as a testing ground for the release process, so that a new contributor learns how to create and release new modules before doing something more serious. If you dig around a bit you might find something useful, or at least a good laugh!