|laziness, impatience, and hubris|
JosÚ's Guide for creating Perl modulesby cog (Parson)
|on Feb 16, 2005 at 19:35 UTC||Need Help??|
In order to answer that question to as many people as possible at the same time, I decided to write this guide.CPAN Search to see if it already exists. If you don't find it at first, search for it under different names; search for its functionality, rather than the name you'd be giving it.
You should do this exhaustively so you don't waste your time duplicating effort.
If your search on CPAN doesn't satisfy you, you can also search Google. A lot of times, the right keywords are in the messages people post about the module but not in the documentation.
Just because a namespace exists doesn't mean you should abandon your module. See if it is any good, if it has everything you'd like it to have, and if it's being maintained. A good alternative is to contact the author and ask him what he thinks about it. Maybe he'll give you the namespace or you can also submit patches for the existing module.
If you need help with any of this, you can ask the PAUSE admins at firstname.lastname@example.org. They will gladly help you with that, and sometimes they even have different means to contact the person.
If you have a name you're not sure about, keep that name in your mind for a couple of days. If you don't think of anything better, it's probably a good name. If the name is really bad, you'll probably think of another one during this time.
As with several other tasks that people do on a daily basis, starting a module from scratch is a task that has been automated... several times! This means you have a range of module creation tools to help you.
h2xs -XAn My::New::Module
The resulting structure is something like this (depending on your version of h2xs).
You're left with a directory with the name of your module, containing a Changes, MANIFEST, Makefile.PL, README, lib/ directory for your modules and a t/ directory for your tests. Not bad...
Without the -b switch, h2xs assumes your module requires your current version of Perl. If your module doesn't have any particular needs for that version, change that! I have been a victim of this in the past, with people sending me e-mails saying "Hey, your module requires Perl 5.8.4, but it would run in 5.6.0. Could you please change that?" Save yourselves that trouble and check that.Module::Starter asks for a few more parameters to start with. Here's an example:
Here's the resulting structure from this:
Looks pretty much the same as the result of h2xs, right? But don't let that fool you! Apart from the new files that test your POD documentation, the contents of those files are different from the ones generated with h2xs. Give a try to both systems and check out the differences.
Currently, I use module-starter to start my own modules.ExtUtils::ModuleMaker is another tool for creating modules. Using the command modulemaker you are taken throught a menu. The resulting structure would be something like this:
You can see some resemblances to the two other systems, right? Notice the Todo and LICENSE files, as well as the scripts directory.
My personal opinion is that you should always start by thinking about what you're doing. This will save time in the long run.
Start with the documentation. My experience tells me that coding gets much easier after you've documented every single one of your functions.
Before actually coding, write down the description of what every function in the module should do. This gives you a chance to figure out what you are doing.
I usually keep a list of modules I'd like to create. Rather than create them when I think about them, I take notes on them from time to time. When the right time comes, I use that list and pick one of the modules with the most notes. Then, I write the documentation.
Tests find things your eye wouldn't catch. As your module evolves, things you left behind can suddenly break. Tests will warn you about them. You should test as much as you can. No test is a test too many.
Test for basic cases, but you should also test the extreme ones. Don't forget to test your functions with and without parameters, and even with parameters in excess, or wrong ones. You should know what those functions return in each of those cases.
Use warnings and strict at the very beginning of scripts or modules.
But there is a downside to using warnings, though: they're not backwards compatible! If your code uses warnings, it won't work with versions of Perl prior to 5.6. You can, however, use warnings while developing and remove them when releasing.
The latest version of Test::Harness turns on warnings while you test, so you might as well make your code warning free.
You're the one who chooses what he's able to import (that is, you can choose not to let a particular function be imported) and how.
Here's an example, to make things easier:
Here's a brief explanation of what is going on in that code:
The last instruction (yes, we're starting by the end) states that whoever uses the module will always get function1. The user gets everything in the @EXPORT array automatically.
The %EXPORT_TAGS hash is kind of an 'alias maker'. In the example, the tag action is mapped into function_make and function_remove, manipulation is mapped into activate_all and deactivate_all, and all is mapped in the four functions. When using a module like this:
use The::Module qw/:action/;
The current package is importing function_make and function_remove.
The @EXPORT_OK is also very important. Things that are not in the @EXPORT variable can only be imported if they are included in @EXPORT_OK.
In this particular example, it's OK to import any of the four functions comprised in the all tag. This means one can do something like this:
use The::Module qw/:action activate_all/;
He will get function_make, function_remove, activate_all and function1 loaded in his package.
If your module is purely object oriented, then you probably won't export anything.
However, if you have functions, you might feel a sudden urge to export some of them.
Do not export functions just because. Instead, make them available to be exported, but let the user select what he wants to use (but don't forget to document the possibilities, of course).
Plus, people HATE changes in the API, so think deeply about it. By not exporting anything, your API will remain the same when you add new functionalities to your module.
So, instead of adding those functions to @EXPORT, try adding them to @EXPORT_OK.
Anyway, browsing a module on the CPAN, people will often look at the README, and if it isn't much, they will very likely take that as a sign that your module isn't really finished.
Both h2xs and module-starter create a standard README file, which you should change and add sections to as you feel the necessity for. I usually copy the POD documentation of my main module to it.
Whenever you add an extra file, don't forget to include it on the MANIFEST file, or your distribution will be incomplete (and, probably, broken).
If you used h2xs, you should check its parameters. Otherwise, you should be fine.
However, there is one situation when you absolutely should update Makefile.PL: when you use other modules. That is, when your module has dependencies.
Just go there and add something like this:
That, for instance, states that your module depends on the existence of at least version 0.01 of Another::Module.
This makes life easier for everybody. The user who's downloading and installing your module automatically doesn't have to spend time figuring out the dependencies, for instance; and CPANPLUS will test your module correctly (hopefully).
When testing, Test::Prereq might be a good option to check whether there are any modules you should add to PREREQ_PM (see section "Make tests", down below).
Do not go from version 0.01 to 1.00 and then to 2.00, because that really looks bad and you'll be in version 20.00 in no time. Instead, go from 0.01 to 0.02, and from there to 0.03, and so on.
Also, there isn't really the necessity of going to 1.00 just from 0.99; people often change the integer part of the version (if one may call it the integer part, given that it is usually a string) when they do major changes in the design of the system, not when they run out of numbers.
Versions which are still being implemented usually have the current version number with an underscore and a number, like 0.04_01 and are called "developer releases"; the underscore makes it clear that the distribution is not yet ready for the general public. You should follow that practice. You can even upload a developer's release to the CPAN. When people look at your module they will see that version, with a red sign stating it's a developer's release and a link to the last ready-to-take version.
Suppose you had forgotten about including something in the MANIFEST, for instance. Just because your module passed all your tests in your specific directory doesn't mean it's working.
That should do it.
If you don't like the PAUSE web interface or you want to automate it, or find it boring or whatever, you can take a look at release and Module::Release, which are tools that automatically upload files to the CPAN and SourceForge.net.
Read perlstyle and Perl::Tidy which show very good ways to tidy up your Perl code.
The Kwalitee project examines distributions on the CPAN for good Perl coding practices, such as the use of strict, existence of tests, and so on. It assigns a score to each distribution, and therefore an average mean to the authors.
Strive for a high Kwalitee score is good for you, your modules, and its users. The higher Kwalitee you get, the bigger your ego becomes, and people consider your modules to be higher quality.
As a module author, you don't have to bother about it; you simply upload your modules to the CPAN and wait to see if anything happens.
If your module's tests fail somewhere, you'll receive a report (actually, you're likely to receive quite a few, given that your module will probably fail on other systems too).
Don't take it too hard if you receive an email with a subject starting with "FAIL Your::Module". It's nothing personal! You screwed up, but it's no big deal, because thanks to the CPAN Testers you are now informed of the problem and you can easily (hopefully) correct it and release a new version.
There, no harm done.
To do that, go to your PAUSE account and use the "Register namespace" option, which is pretty simple to use. You'll have to elaborate on how and why is your module important, but it's not that difficult, really.
When people look at your home node on CPAN Search (http://search.cpan.org/~yourusername), they will see all your modules and a list of the registered ones, along with some information on those.
A registered module was approved by PAUSE admins. Therefore, it's not simply a product of some delusional visionist with headaches and is probably something good, unless, of course, some PAUSE admin that day was a delusional visionist and had an headache.
There's nothing wrong in having a bunch of modules you haven't completed yet, but there is something wrong in having a bunch of modules you will never complete.
If you still have doubts (or maybe even more than when you started), there are lots of people willing to help (and of course I'm one of them).
Check out the email@example.com mailing list.
For anything else, I'm cog at cpan dot org.