Always Begin with h2xs

Chapter 4 - CPAN Module Distributions
by?Sam Tregar?
Apress ? 2002
has companion web siteCompanion Web Site

The Perl documentation on building a module distribution[3] contains the excellent advice, "Start with h2xs." The documentation for ExtUtils::MakeMaker,[4] the module responsible for making Makefile.PL work, elaborates:

  • Always begin with h2xs.

  • Always begin with h2xs!

  • ALWAYS BEGIN WITH H2XS!

This is good advice because using h2xs can save you a lot trouble, and I'll show you how to follow it. Perl comes with a program called h2xs[5] that can be used to generate the skeleton[6] of a module distribution. Its rather obscure name comes from the fact that it was originally designed as a tool to generate XS[7] modules from C header files.

As an example, I'll create a module distribution for a fictitious module called Data::Counter. To use h2xs to generate the module skeleton for Data::Counter, I use the following command:

 h2xs -XA -n Data::Counter 

This command creates the directory structure shown in Figure 4-1 and Table 4-1 beneath the directory where the command was run. The -X option tells h2xs not to generate any XS files and the -A option causes h2xs to omit Autoloader support. The -n option tells h2xs the name of the module to be created. h2xs uses the module name to create a directory to hold the generated files.

click to expand
Figure 4-1: Directory structure created by h2xs -XA -n Data::Counter

Table 4-1: Files Generated by h2xs

File

Description


Counter.pm

The module file itself, containing Perl code and POD documentation


Makefile.PL

A script that uses ExtUtils::MakeMaker to generate a Makefile


test.pl

A test script run when a user enters "make test" or installs your module with the CPAN module


README

A quick description of your module and how to install it


Changes

A change-log where you can describe differences between versions of your module


MANIFEST

A list of all the files in your distribution

Counter.pm-The Module File

The module file generated by h2xs (see Listing 4-1) is a generic template into which I'll place the code and documentation for Data::Counter. However, before I blow away what's there, let's look at the generated template; it uses some features that might be new to you.

Listing 4-1: Counter.pm File Generated by h2xs

start example
 package Data::Counter; use 5.006; use strict; use warnings; require Exporter; our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use Data::Counter ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. our %EXPORT_TAGS = ( 'all' => [ qw( ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( ); our $VERSION = '0.01'; # Preloaded methods go here. 1; __END__ # Below is stub documentation for your module. You better edit it! =head1 NAME Data::Counter - Perl extension for blah blah blah =head1 SYNOPSIS   use Data::Counter;   blah blah blah =head1 DESCRIPTION Stub documentation for Data::Counter, created by h2xs. It looks like the author of the extension was negligent enough to leave the stub unedited. Blah blah blah. =head2 EXPORT None by default. =head1 AUTHOR A. U. Thor, E<lt>a.u.thor@a.galaxy.far.far.awayE<gt> =head1 SEE ALSO L<perl>. =cut 
end example

First, h2xs encourages you to be explicit about the version of Perl required by your code:

 use 5.006; 

If this module were used in a version of Perl older than 5.6.0,[8] an error message would be generated stating that a newer version of Perl is required. Actually, as you'll see later, it's better to put this check in Makefile.PL, but the intent is the same.

Next h2xs includes the following use lines:

 use strict; use warnings; 

So far, I've avoided the strict and warnings pragmas in order to keep the examples simple, but the buck stops here. All CPAN modules should include use strict and use warnings, and Data::Counter won't be an exception! By using these two pragmas, your module will be free from the most common problems occurring in Perl programs. For more information on these most useful of pragmas, see the documentation for strict and warnings as well as the coverage in most good introductory Perl books.

The next section of code deals with using the Exporter correctly. It not only sets up @ISA but also includes helpful commentary about how to use the various package variables employed by Exporter-@EXPORT, @EXPORT_OK, and %EXPORT. This might seem like overkill, but there was once a time when Exporter abuse was rampant throughout CPAN. If you don't need to export any symbols, then you can delete the entire section, until the $VERSION line.

The next line sets up $VERSION:

 our $VERSION = '0.01'; 

This variable is needed by all CPAN modules. Without it, the CPAN module won't know which version of your module to install, and make dist (discussed later) won't be able to create a distribution archive. By convention most CPAN modules start their lives at version 0.01, but you are free to use any number you like.

Caution 

You might be tempted to start with a version like 0.1 instead of 0.01, but that can cause problems later when you want to release a version after 0.9 but aren't ready for the psychological impact of releasing 1.0.

After the $VERSION assignment, h2xs includes the cryptic comment "preloaded methods go here." You can read that as "your module code goes here." The term "preloaded" is a reference to h2xs's support for the AutoLoader module, which makes a distinction between "preloaded" and "autoloaded" subroutines and methods

Finally, h2xs includes some example POD documentation after the requisite final true statement. The example POD contains the sections that most CPAN modules will need-NAME, SYNOPSIS, DESCRIPTION, EXPORT, AUTHOR, and SEE ALSO. Of course, unless your module is very simple, you'll need to add sections that describe the available subroutines and methods. Also, unless your module uses the Exporter, it's safe to remove EXPORT.

An edited version of Counter.pm containing the code and documentation for the module is shown in Listing 4-2.

Listing 4-2: Modified Counter.pm for Data::Counter

start example
 package Data::Counter; use 5.006;  # this will be checked in Makefile.PL too use strict; use warnings; # make count() available for optional exporting require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = ( 'count' ); our $VERSION = '0.01'; # return a count of arguments sub count {   return scalar @_; } 1; __END__ =head1 NAME Data::Counter - Perl extension to count data items. =head1 SYNOPSIS   use Data::Counter qw(count);   print count("one", "two", "three"); # prints 3 =head1 DESCRIPTION This module provides a single function, count(), that counts its arguments. =over 4 =item $num = count($item1, $item2, ...) This subroutine returns the number of items passed as arguments. =head2 EXPORT The 'count' routine is available for optional export. =head1 AUTHOR Sam Tregar <sam@tregar.com> =head1 SEE ALSO L<perl>. =cut 
end example

Makefile.PL-The Makefile Generator

The core of a CPAN distribution is the Makefile.PL script. Running Makefile.PL generates a Makefile that drives the rest of the build, test, and installation procedure. You might wonder why a module couldn't just include a Makefile outright-the reason is portability. Most operating systems have some kind of make utility, but the format and syntax of their Makefiles differ significantly. Also, the Makefile needs to know how Perl was configured in order to do its job. Hence, the solution is to have a Perl script that generates a Makefile appropriate for the system where the module is being installed.

start sidebar
What's a Makefile?

If you don't come from a UNIX programming background, you might not be familiar with Makefiles. A Makefile is a script processed by a program called make.[9] When make is run, it automatically looks for a file called Makefile in the current directory. make uses the information stored in the Makefile to perform the steps necessary to build and install programs from source files. To accomplish this task, a Makefile specifies a set of rules and dependencies.

A Makefile rule is a particular step in the build process-examples of rules you've seen so far include "test" and "install". When you run the command make test, you're instructing make to run the "test" rule in the Makefile. Makefiles also support the notion of a default rule that is run when no rule is explicitly specified, usually called "all".

Aside from rules that specify activities such as make test and make install, Makefiles also have rules for creating files. One example of this type of rule is the one used to turn a module's POD documentation into a UNIX manual page through the pod2man program.

Makefiles combine rules by laying out rule dependencies. For example, the "all" rule depends on the rule to build manual pages from POD documentation, among others. Dependencies work in two ways. First, they specify a series of steps describing how to complete a requested rule. Second, they allow make to intelligently skip rules when it can tell that the target is up-to-date. For example, make can tell that it doesn't need to rerun pod2man unless the module file containing the POD has been changed since the last time pod2man was run.

For more information about how Makefiles work on your system, see the documentation for your make command.

end sidebar

The Makefile.PL that h2xs generates (see Listing 4-3) for Data::Counter is a simple Perl script. The script uses a single module-ExtUtils::MakeMaker.[10] The subroutine WriteMakefile() is exported from ExtUtils::MakeMaker by default.

Listing 4-3: Makefile.PL Generated by h2xs

start example
 use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile(     'NAME'               => 'Data::Counter',     'VERSION_FROM'       => 'Counter.pm', # finds $VERSION     'PREREQ_PM'          => {}, # e.g., Module::Name => 1.1     ($] >= 5.005 ?   ## Add these new keywords supported since 5.005       (ABSTRACT_FROM     => 'Counter.pm', # retrieve abstract from modul        AUTHOR            => 'A. U. Thor <a.u.thor@a.galaxy.far.far.away>') : ()), ); 
end example

WriteMakefile() employs the named-parameter style discussed in Chapter 3 using the parameters NAME, VERSION_FROM, PREREQ_PM, ABSTRACT_FROM, and AUTHOR. The first parameter, NAME, is the name of your module. The second parameter here is VERSION_FROM, which tells ExtUtils::MakeMaker where to look for the $VERSION setting. This is necessary because a module distribution may have more than one module. I will discuss multimodule distributions in depth later in the chapter.

The next parameter, PREREQ_PM, is initially empty, but is important enough that h2xs includes it as a reminder. PREREQ_PM specifies your module's dependencies. By including information on which other modules your module uses, you allow the CPAN module to do its job much better. For example, if Data::Counter uses CGI::Application, I would change the PREREQ_PM line to read as follows:

 'PREREQ_PM' => { 'CGI::Application' => 0 }, 

The keys of the PREREQ_PM hash are module names, and the values are version numbers. By specifying a version number of zero, I'm telling ExtUtils::MakeMaker that I need some version of CGI::Application installed, but I don't care which one. To specify that I need at least version 1.3 installed, I would use this setting:

 'PREREQ_PM' => { 'CGI::Application' => 1.3 }, 

Now when a user tries to install Data::Counter using the CPAN module, CGI::Application will be automatically installed. Using PREREQ_PM prevents users from discovering a dependency when they try to use the module by advising them when the module is installed. This ensures that the system is not cluttered with half-working code.

Caution 

It is important to include all modules that your module uses in PREREQ_PM, even ones that come with Perl. Unfortunately, many packagers of Perl choose to not include some or all of the optional modules usually included with Perl. Thus, even if a module is installed by default on your system, some of your users may need to install the module from CPAN.

Note 

There is no way to specify that your module needs an exact version of another module and won't work with a later, higher-numbered version. To do this you'll need to add code to your Makefile.PL to explicitly check for the version you need.

The next section is somewhat curious:

 ($] >= 5.005 ?  ## Add these new keywords supported since 5.005   (ABSTRACT_FROM    => 'Counter.pm', # retrieve abstract from module    AUTHOR           => 'A. U. Thor <a.u.thor@a.galaxy.far.far.away>') : ()), 

It checks to see if the Perl version is 5.005 or greater and then defines some parameters if it is. This seems to be at odds with the module file that h2xs generates. Although Makefile.PL goes out of its way to support older versions of Perl, the generated module file will only work with rather new versions! In fact, it would be better if the required Perl version were checked in Makefile.PL rather than in the module file itself. That way version incompatibility is discovered as early as possible, saving users from downloading prerequisite modules for a module that they won't be able to use. For example, to include a version check for Perl 5.6.0, I add this line at the top of Data::Counter's Makefile.PL:

 use 5.006; 

This is needed since Data::Counter uses the new our keyword, which isn't available before version 5.6.0.

The parameters that are set inside the check for 5.005 are ABSTRACT_FROM and AUTHOR. ExtUtils::MakeMaker uses ABSTRACT_FROM to search for a one-line description of your module. It does so by looking for a line that starts with your module name and a dash. Everything after the dash is the module's abstract.[11] For example, here's the section from Data::Counter's module file where the abstract would be extracted:

 Data::Counter - Perl extension to count data items. 

Finally, the AUTHOR parameter gives the name and e-mail address for the author of the module.

The Makefile.PL for Data::Counter is in Listing 4-4. This is a simple Makefile.PL; for more information about Makefile.PL techniques, see the "Exploring the Distribution" section later in this chapter.

Listing 4-4: Modified Makefile.PL for Data::Counter

start example
 use ExtUtils::MakeMaker; use 5.006;  # this module requires Perl 5.6.0 WriteMakefile(     NAME                => "Data::Counter",     VERSION_FROM        => "Counter.pm",     ABSTRACT_FROM       => "Counter.pm",     AUTHOR              => 'Sam Tregar <sam@tregar.com>' ); 
end example

test.pl The Test Script

h2xs generates a simple test script that you can use to build regression tests for your module. A regression test is a test that proves a described feature performs the way it is supposed to work. By developing regression tests for your module, you'll be sure that your module works the way your documentation says it does. Also, when you fix a bug, you can add a regression test to prove that it's fixed-after which you can be sure that the bug will never be reintroduced into your module. Similarly, when you add a new feature, you can add a new test so that you can be sure the feature works as advertised.

The generated test script (see Listing 4-5) is a normal Perl script that uses a module called Test.[12] The Test module exports a subroutine called plan(), which must be called before any tests. In this case, plan() is called inside a BEGIN block with a single named parameter, tests, giving the number of tests to be run. When you add a test to the script, you'll need to update this number.

Listing 4-5: test.pl Generated by h2xs

start example
 # Before 'make install' is performed this script should be runnable with # 'make test'. After 'make install' it should work as 'perl test.pl' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test; BEGIN { plan tests => 1 }; use Data::Counter; ok(1); # If we made it this far, we're ok. ######################### # Insert your test code below, the Test module is use()ed here so read # its man page ( perldoc Test ) for help writing this test script. 
end example

The default test script includes one test-it attempts to load Data::Counter and automatically succeeds if that didn't cause the script to die. Another use of the ok() function is to test that a returned value is what it should be. For example, Data::Counter has a test for the count() subroutine that checks whether count() returns 3 when it is called with three arguments:

 ok(count("one", "two", "three") == 3); 

After adding this test case, a make test run looks like the following:

 $ make test PERL_DL_NONLAZY=1 /usr/local/bin/perl -Iblib/arch -Iblib/lib \ -I/usr/local/lib/perl5/5.6.1/i686-linux -I/usr/local/lib/perl5/5.6.1 test.pl 1..2 ok 1 ok 2 

If count() were broken, the output would look like this:

 1..2 ok 1 not ok 2 # Failed test 2 in test.pl at line 18 

The last line tells you which test failed and where to look in test.pl for the failing test.

The complete test script for Data::Counter is included in Listing 4-6.

Listing 4-6: Modified test.pl for Data::Counter

start example
 use Test; BEGIN { plan tests => 2 }; use Data::Counter qw(count); ok(1); # If we made it this far, we're ok. # make sure count works ok(count("one", "two", "three") == 3); 
end example

README

The README file is often a potential user's first contact with a module. When you upload a module to CPAN, the README file is extracted and placed alongside the module. Its job is to introduce the module and give information about installation. The generated README (see Listing 4-7) is self-explanatory. Some of the information is redundant-the header contains the version number that you'll also specify in your module file, and the list of dependencies should be the same as the information in your Makefile.PL PREREQ_PM setting. This means that you'll have to be careful to keep the information in the README up-to-date as your module changes. Don't worry about the COPYRIGHT AND LICENSE section for now-I'll be covering this in detail later in this chapter.

Listing 4-7: README Generated by h2xs

start example
 Data/Counter version 0.01 ======================== The README is used to introduce the module and provide instructions on how to install the module, any machine dependencies it may have (for example C compilers and installed libraries) and any other information that should be provided before the module is installed. A README file is required for CPAN modules since CPAN extracts the README file from a module distribution so that people browsing the archive can use it get an idea of the modules uses. It is usually a good idea to provide version information here so that people can decide whether fixes for the module are worth downloading. INSTALLATION To install this module type the following:    perl Makefile.PL    make    make test    make install DEPENDENCIES This module requires these other modules and libraries:  blah blah blah COPYRIGHT AND LICENCE Put the correct copyright and licence information here. Copyright (C) 2001 A. U. Thor blah blah blah 
end example

Changes

The Changes file (see Listing 4-8) provides a place for you to record changes to your module as you release new versions. Using this file to record bug fixes and new features will help your users stay up-to-date on the module's development.

Listing 4-8: Changes File Generated by h2xs

start example
 Revision history for Perl extension Data::Counter. 0.01 Sat Dec 1 17:10:07 2001            - original version; created by h2xs 1.21 with options        -XA -n Data::Counter 
end example

MANIFEST

The MANIFEST file (see Listing 4-9) contains a list of all the files in your module distribution. ExtUtils::MakeMaker uses this list to build the distribution file itself (described later in this chapter) and to check to make sure that the module distribution is complete on the user's system before installation. You'll need to keep this file up-to-date as you add files to your distribution.

Listing 4-9: MANIFEST Generated by h2xs.

start example
 Changes Makefile.PL MANIFEST Counter.pm README test.pl 
end example

[3]perlnewmod, written by Simon Cozens

[4]Written by Andy Dougherty, Andreas Köenig, Tim Bunce, Charles Bailey, and Ilya Zakharevich. It is included with Perl.

[5]Written by Larry Wall and others. I'm using version 1.21.

[6]No black magic required-this just means that h2xs creates a set of mostly empty files for you to flesh out to complete your module distribution.

[7]XS is the name for Perl's C language extension system. See Chapter 9 for details.

[8]So why doesn't it say "use 5.6.0"? Support for X.Y.Z format numbers, called v-strings, is itself a feature of modern versions of Perl. Since the purpose of this line is to produce a sensible error message in old versions of Perl, it can't use a v-string to express the version number.

[9]Or, on Microsoft Windows systems, possibly dmake or nmake. See the "Installing CPAN Modules" section in Chapter 1 for details.

[10]Written by Andy Dougherty, Andreas Köenig, Tim Bunce, Charles Bailey and Ilya Zakharevich. It is included with Perl.

[11]For the regex literate: /^$package\s-\s(.*)/

[12]Written by Joshua Nathaniel Pritikin



Writing Perl Modules for CPAN
Writing Perl Modules for CPAN
ISBN: 159059018X
EAN: 2147483647
Year: 2002
Pages: 110
Authors: Sam Tregar

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net