I've been writing a *lot* of perl modules lately (mostly internal stuff), and so I've been thinking a lot about what are the best practices for writing modules... Here's my random thoughts:
1. Don't use h2xs. It just sucks so bad. Here's my recipe for creating a new perl module:
mkdir <ModuleName>
cd <ModuleName>
mkdir t
mkdir lib
mkdir lib/<ModuleName> (make any subdirs too)
touch README MANIFEST MANIFEST.SKIP Makefile.PL Changes
touch lib/<ModuleName>.pm
touch t/00basic.t
Note that sometimes there you'll need to make more directories under lib/ if your module is deeply nested.
2. Edit Makefile.PL to look something like:
use ExtUtils::MakeMaker;
WriteMakefile(
'NAME' => '<ModuleName>',
'VERSION_FROM' => 'lib/<ModuleName>.pm',
'PREREQ_PM' => {},
'ABSTRACT_FROM' => 'lib/<ModuleName>.pm',
'AUTHOR' => 'Matt Sergeant <matt@sergeant.org>',
);
Note that I don't put any of the *useless* comments in that h2xs gives you... I mean, really do we need VERSION_FROM to have a comment that says "finds $VERSION" ???
3. Edit t/00basic.t to look something like:
use Test;
BEGIN { plan tests => 1 }
END { ok($loaded) }
use <ModuleName>;
$loaded++;
4. Edit MANIFEST.SKIP to look something like:
CVS/.*
\.bak$
\.sw[a-z]$
\.tar$
\.tgz$
\.tar\.gz$
^mess/
^tmp/
^blib/
^Makefile$
^Makefile\.[a-z]+$
^pm_to_blib$
~$
5. Start editing lib/<ModuleName>.pm
I'm not going to tell you how to write a module here. But once again, a lot of the h2xs cruft I used to manually remove by hand, but now I just write my own module, making sure I use strict, end in "1;", and add some POD.
Now run perl Makefile.PL, then make manifest, then make realclean.
A couple of the "best practices" that the above does, that I consider important are:
1. You get the lib/ structure for your module, rather than the default h2xs method of dumping
2. You start off right away with tests in the t/ directory, and they use the Test.pm module. Note some often un-mentioned features of Test::Harness - the ability to specify TEST_VERBOSE=1 and TEST_FILES=t/01foo.t on the command line, which gives you more verbose output, and the ability to do individual tests without having to run your entire test suite:
make test TEST_VERBOSE=1 TEST_FILES=t/01foo.t
This will also tell you exactly where the test failure was (a line number) and why it failed, if you're using Test.pm's ok() function (e.g. "got 'flugebar', expected 'dungbeetle'").
The only thing I really miss is the ability to have
Anyway, hope this helps someone.
OK. Thanks! (Score:1)
use warnings;
use strict;
my($MODNAME) = @ARGV;
mkdir($MODNAME);
chdir($MODNAME);
mkdir("t");
mkdir("lib");
mkdir("lib/$MODNAME");
my $fh;
foreach my $file (qw(README MANIFEST MANIFEST.SKIP Makefile.PL Changes))
{
open($fh, ">$file");
}
open($fh, ">lib/$MODNAME.pm");
open($fh, ">t/00basic.t");
open($fh, ">Makefile.PL") || die "Can't open Makefile.PL: $!";
print $fh <<"EOF";
use ExtUtils::MakeMaker;
WriteMakefile(
'N
J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
Re:OK. Thanks! (Score:1)
Matt, can't tell you how helpful you've been to me in the past. Hope this helps you a little, or at least spurs some further thought. :) Obviously I'll be immediately updating my own personal copy of this not to say matt@sergeant.org for AUTHOR.
Being the freak that I am, I'll also probably add strict and warnings to the test script, and add the package $MODNAME; and 1; statements into $MODNAME.pm.
J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
Re:OK. Thanks! (Score:1)
Re:OK. Thanks! (Score:1)
Yes. I started thinking about that and then decided I would never get the program written, let alone posted, if I handled that issue.
But, as the rough rocks in a stream get worn down smooth, I'm sure I will walk across that enough times in the future I (or someone else) will be motivated to fix that.
Hmmmmm. How about Inline::Files to hold to contents of all those files that get set up?
J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
Re:OK. Thanks! (Score:1)
Done. :) It's in my journal, but I'm not sure if anyone's seen it. Am I the only one who ever looks at journals at random? I've got the journals slashbox at the top on my page.
J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
Re:OK. Thanks! (Score:1)
It would be nice to see a feature that lists journal entries since a particular date.
---ict / Spoon