diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2000-05-29 17:56:26 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2000-05-29 17:56:26 +0000 |
commit | 2e1d04bc4fa2d036f823d5251c731f594e0246dd (patch) | |
tree | 9576f0c7ce6edb3860c7ae7a62167ac9fe4c308c /pod/perlnewmod.pod | |
parent | e2cf2bdb3ec4f6752299142b6793db46c2033302 (diff) | |
download | perl-2e1d04bc4fa2d036f823d5251c731f594e0246dd.tar.gz |
Add autogeneration of perlmodlib.pod and the new perlnewmod.pod,
both from Simon Cozens.
p4raw-id: //depot/cfgperl@6161
Diffstat (limited to 'pod/perlnewmod.pod')
-rw-r--r-- | pod/perlnewmod.pod | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/pod/perlnewmod.pod b/pod/perlnewmod.pod new file mode 100644 index 0000000000..1e4a9c3b29 --- /dev/null +++ b/pod/perlnewmod.pod @@ -0,0 +1,282 @@ +=head1 NAME + +perlnewmod - preparing a new module for distribution + +=head1 DESCRIPTION + +This document gives you some suggestions about how to go about writing +Perl modules, preparing them for distribution, and making them available +via CPAN. + +One of the things that makes Perl really powerful is the fact that Perl +hackers tend to want to share the solutions to problems they've faced, +so you and I don't have to battle with the same problem again. + +The main way they do this is by abstracting the solution into a Perl +module. If you don't know what one of these is, the rest of this +document isn't going to be much use to you. You're also missing out on +an awful lot of useful code; consider having a look at L<perlmod>, +L<perlmodlib> and L<perlmodinstall> before coming back here. + +When you've found that there isn't a module available for what you're +trying to do, and you've had to write the code yourself, consider +packaging up the solution into a module and uploading it to CPAN so that +others can benefit. + +=head2 Warning + +We're going to primarily concentrate on Perl-only modules here, rather +than XS modules. XS modules serve a rather different purpose, and +you should consider different things before distributing them - the +popularity of the library you are gluing, the portability to other +operating systems, and so on. However, the notes on preparing the Perl +side of the module and packaging and distributing it will apply equally +well to an XS module as a pure-Perl one. + +=head2 What should I make into a module? + +You should make a module out of any code that you think is going to be +useful to others. Anything that's likely to fill a hole in the communal +library and which someone else can slot directly into their program. Any +part of your code which you can isolate and extract and plug into +something else is a likely candidate. + +Let's take an example. Suppose you're reading in data from a local +format into a hash-of-hashes in Perl, turning that into a tree, walking +the tree and then piping each node to an Acme Transmogrifier Server. + +Now, quite a few people have the Acme Transmogrifier, and you've had to +write something to talk the protocol from scratch - you'd almost +certainly want to make that into a module. The level at which you pitch +it is up to you: you might want protocol-level modules analogous to +L<Net::SMTP|Net::SMTP> which then talk to higher level modules analogous +to L<Mail::Send|Mail::Send>. The choice is yours, but you do want to get +a module out for that server protocol. + +Nobody else on the planet is going to talk your local data format, so we +can ignore that. But what about the thing in the middle? Building tree +structures from Perl variables and then traversing them is a nice, +general problem, and if nobody's already written a module that does +that, you might want to modularise that code too. + +So hopefully you've now got a few ideas about what's good to modularise. +Let's now see how it's done. + +=head2 Step-by-step: Preparing the ground + +Before we even start scraping out the code, there are a few things we'll +want to do in advance. + +=over 3 + +=item Look around + +Dig into a bunch of modules to see how they're written. I'd suggest +starting with L<Text::Tabs|Text::Tabs>, since it's in the standard +library and is nice and simple, and then looking at something like +L<Time::Zone|Time::Zone>, L<File::Copy|File::Copy> and then some of the +C<Mail::*> modules if you're planning on writing object oriented code. + +These should give you an overall feel for how modules are laid out and +written. + +=item Check it's new + +There are a lot of modules on CPAN, and it's easy to miss one that's +similar to what you're planning on contributing. Have a good plough +through the modules list and the F<by-module> directories, and make sure +you're not the one reinventing the wheel! + +=item Discuss the need + +You might love it. You might feel that everyone else needs it. But there +might not actually be any real demand for it out there. If you're unsure +about the demand you're module will have, consider sending out feelers +on the C<comp.lang.perl.modules> newsgroup, or as a last resort, ask the +modules list at C<modules@perl.org>. Remember that this is a closed list +with a very long turn-around time - be prepared to wait a good while for +a response from them. + +=item Choose a name + +Perl modules included on CPAN have a naming hierarchy you should try to +fit in with. See L<perlmodlib> for more details on how this works, and +browse around CPAN and the modules list to get a feel of it. At the very +least, remember this: modules should be title capitalised, (This::Thing) +fit in with a category, and explain their purpose succinctly. + +=item Check again + +While you're doing that, make really sure you haven't missed a module +similar to the one you're about to write. + +When you've got your name sorted out and you're sure that your module is +wanted and not currently available, it's time to start coding. + +=back + +=head2 Step-by-step: Making the module + +=over 3 + +=item Start with F<h2xs> + +Originally a utility to convert C header files into XS modules, +L<h2xs|h2xs> has become a useful utility for churning out skeletons for +Perl-only modules as well. If you don't want to use the +L<Autoloader|Autoloader> which splits up big modules into smaller +subroutine-sized chunks, you'll say something like this: + + h2xs -AX -n Net::Acme + +The C<-A> omits the Autoloader code, C<-X> omits XS elements, and C<-n> +specifies the name of the module. + +=item Use L<strict|strict> and L<warnings|warnings> + +A module's code has to be warning and strict-clean, since you can't +guarantee the conditions that it'll be used under. Besides, you wouldn't +want to distribute code that wasn't warning or strict-clean anyway, +right? + +=item Use L<Carp|Carp> + +The L<Carp|Carp> module allows you to present your error messages from +the caller's perspective; this gives you a way to signal a problem with +the caller and not your module. For instance, if you say this: + + warn "No hostname given"; + +the user will see something like this: + + No hostname given at /usr/local/lib/perl5/site_perl/5.6.0/Net/Acme.pm + line 123. + +which looks like your module is doing something wrong. Instead, you want +to put the blame on the user, and say this: + + No hostname given at bad_code, line 10. + +You do this by using L<Carp|Carp> and replacing your C<warn>s with +C<carp>s. If you need to C<die>, say C<croak> instead. However, keep +C<warn> and C<die> in place for your sanity checks - where it really is +your module at fault. + +=item Use L<Exporter|Exporter> - wisely! + +C<h2xs> provides stubs for L<Exporter|Exporter>, which gives you a +standard way of exporting symbols and subroutines from your module into +the caller's namespace. For instance, saying C<use Net::Acme qw(&frob)> +would import the C<frob> subroutine. + +The package variable C<@EXPORT> will determine which symbols will get +exported when the caller simply says C<use Net::Acme> - you will hardly +ever want to put anything in there. C<@EXPORT_OK>, on the other hand, +specifies which symbols you're willing to export. If you do want to +export a bunch of symbols, use the C<%EXPORT_TAGS> and define a standard +export set - look at L<Exporter> for more details. + +=item Use L<plain old documentation|perlpod> + +The work isn't over until the paperwork is done, and you're going to +need to put in some time writing some documentation for your module. +C<h2xs> will provide a stub for you to fill in; if you're not sure about +the format, look at L<perlpod> for an introduction. Provide a good +synopsis of how your module is used in code, a description, and then +notes on the syntax and function of the individual subroutines or +methods. Use Perl comments for developer notes and POD for end-user +notes. + +=item Write tests + +You're encouraged to create self-tests for your module to ensure it's +working as intended on the myriad platforms Perl supports; if you upload +your module to CPAN, a host of testers will build your module and send +you the results of the tests. Again, C<h2xs> provides a test framework +which you can extend - you should do something more than just checking +your module will compile. + +=item Write the README + +If you're uploading to CPAN, the automated gremlins will extract the +README file and place that in your CPAN directory. It'll also appear in +the main F<by-module> and F<by-category> directories if you make it onto +the modules list. It's a good idea to put here what the module actually +does in detail, and the user-visible changes since the last release. + +=back + +=head2 Step-by-step: Distributing your module + +=over 3 + +=item Get a CPAN user ID + +Every developer publishing modules on CPAN needs a CPAN ID. See the +instructions at C<http://www.cpan.org/modules/04pause.html> (or +equivalent on your nearest mirror) to find out how to do this. + +=item C<perl Makefile.PL; make test; make dist> + +Once again, C<h2xs> has done all the work for you. It produces the +standard C<Makefile.PL> you'll have seen when you downloaded and +installs modules, and this produces a Makefile with a C<dist> target. + +Once you've ensured that your module passes its own tests - always a +good thing to make sure - you can C<make dist>, and the Makefile will +hopefully produce you a nice tarball of your module, ready for upliad. + +=item Upload the tarball + +The email you got when you received your CPAN ID will tell you how to +log in to PAUSE, the Perl Authors Upload SErver. From the menus there, +you can upload your module to CPAN. + +=item Announce to the modules list + +Once uploaded, it'll sit unnoticed in your author directory. If you want +it connected to the rest of the CPAN, you'll need to tell the modules +list about it. The best way to do this is to email them a line in the +style of the modules list, like this: + + Net::Acme bdpO Interface to Acme Frobnicator servers FOOBAR + ^ ^^^^ ^ ^ + | |||| Module description Your ID + | |||| + | |||\- Interface: (O)OP, (r)eferences, (h)ybrid, (f)unctions + | ||| + | ||\-- Language: (p)ure Perl, C(+)+, (h)ybrid, (C), (o)ther + | || + Module |\--- Support: (d)eveloper, (m)ailing list, (u)senet, (n)one + Name | + \---- Maturity: (i)dea, (c)onstructions, (a)lpha, (b)eta, + (R)eleased, (M)ature, (S)tandard + +plus a description of the module and why you think it should be +included. If you hear nothing back, that means your module will +probably appear on the modules list at the next update. Don't try +subscribing to C<modules@perl.org>; it's not another mailing list. Just +have patience. + +=item Announce to clpa + +If you have a burning desire to tell the world about your release, post +an announcement to the moderated C<comp.lang.perl.announce> newsgroup. + +=item Fix bugs! + +Once you start accumulating users, they'll send you bug reports. If +you're lucky, they'll even send you patches. Welcome to the joys of +maintaining a software project... + +=back + +=head1 AUTHOR + +Simon Cozens, C<simon@cpan.org> + +=head1 SEE ALSO + +L<perlmod>, L<perlmodlib>, L<perlmodinstall>, L<h2xs>, L<strict>, +L<Carp>, L<Exporter>, L<perlpod>, L<Test>, L<ExtUtils::MakeMaker>, +http://www.cpan.org/ |