Hundreds of Perl modules are available to expand the language for almost any task. There are even modules, such as CPAN.pm and Devel::Modlist, to help manage the modules you use.
One of strengths of the Perl language is its extendability through third party
modules, and hundreds of them are available on the
href="http://search.cpan.org">Comprehensive Perl Archive Network (CPAN)
Modules have names (typically their namespace name) and versions, and may come
in bundles, which are lists of modules that go together. Some modules need other
modules, so they have dependencies.
Installing modules is made easier with
href="http://search.cpan.org/search?dist=CPAN">CPAN.pm
Konig that does all of the hard work for you. You can quickly lose track of
the modules that your application needs, and which modules you need to tell
your users to install. The module names that you actually type into your source
code are most likely not the only modules you'll use.
For instance, you might use the extremely powerful
href="http://search.cpan.org/search?dist=LWP-Simple">LWP::Simple
a simple script that superficially does not use any other modules.
#!/usr/bin/perl use LWP::Simple; getprint( "http://www.perl.org" ); __END__
|
Behind the scenes, however,
href="http://search.cpan.org/search?dist=LWP-Simple">LWP::Simple
many other modules to do its work. Here is a complete list of all the modules
it might possibly use:
AutoLoader 5.57 Carp Config DynaLoader 1.04 Errno 1.111 Exporter 5.562 Exporter::Heavy HTML::Entities 1.21 HTML::HeadParser 2.14 HTML::Parser 3.18 HTTP::Date 1.43 HTTP::Headers 1.37 HTTP::Message 1.23 HTTP::Request 1.27 HTTP::Response 1.34 HTTP::Status 1.26 IO 1.20 IO::Handle 1.21 IO::Select 1.14 IO::Socket 1.26 IO::Socket::INET 1.25 IO::Socket::UNIX 1.20 LWP 5.51 LWP::Debug LWP::MemberMixin LWP::Protocol 1.36 LWP::Protocol::http LWP::Simple 1.33 LWP::UserAgent 1.77 SelectSaver Socket 1.72 Symbol 1.02 Time::Local URI 1.11 URI::Escape 3.16 URI::URL 5.02 URI::WithBase URI::_generic URI::_query URI::_server URI::http XSLoader 0.01 overload strict 1.01 vars warnings warnings::register
|
This presents a couple of maintenance problems. You develop your software with
one version of a module, but another version of the same module does something
slightly different, and earlier versions may have a bug. Or perhaps you want to
set up your staging server with exactly the same module configuration as your
production server. How do you determine which modules (and which versions) to
install with your application when it is not readily apparent from looking at
the source? How do you even know which modules you have installed?
You need to figure out which modules are currently installed and which modules
you are really using. The
href="http://search.cpan.org/search?dist=CPAN">CPAN.pm
called autobundle
which will analyze your installed modules and
give you a list of the ones currently on CPAN.
The modules not in the list are the ones in the standard library that comes
with Perl, or the ones that you have installed locally and should already know
about.
perl -MCPAN -e autobundle
|
href="http://search.cpan.org/search?dist=CPAN">CPAN.pm
modules in the .cpan
directory in a special type of module called
a Bundle file, which is just a special type of module. Take a look at the
bundle for my machine
href="http://search.cpan.org/search?dist=CPAN">CPAN.pm
install groups of modules. In this case you can create a bundle just for the modules
that your application needs. If you can give your users the bundle file, they
can use
href="http://search.cpan.org/search?dist=CPAN">CPAN.pm
they need, but let's come back to that. For more details about how Bundle files
work, see the documentation for
href="http://search.cpan.org/search?dist=CPAN">CPAN.pm
Keeping track of all the modules used in your software can be difficult. Luckily
there's module to do this for you:
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
handy debugger module can analyze your installed modules and give you various
lists of them depending on what you want to see. Indeed, I used it to created
the earlier list of modules. Just as with other Perl debuggers, you activate
the
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
with the
href="http://www.perldoc.com/perl5.6/pod/perlrun.html">-d
perl -d:Modlist script.pl
|
Try it on one of your scripts and see what you get. You may be surprised about
how much is happening behind the scenes. Without CPAN
you would have had to create all of that code yourself. Next time your favorite
module author is in town make sure you treat them to a few drinks!
Notice that when you use the
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
your script still runs and does whatever it does. You can stop the script from
executing but still get the module list by passing
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
parameters, although you have to call it in a slightly different way. To do
this you still use the
href="http://www.perldoc.com/perl5.6/pod/perlrun.html">-d
the debugger, but you have to use the
href="http://www.perldoc.com/perl5.6/pod/perlrun.html">-M
the
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
since
href="http://www.perldoc.com/perl5.6/pod/perlrun.html">-M
information to the module. In this case, you want to pass the stop
command to
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
perl -d -MDevel::Modlist=stop script.pl
|
You get the same module list as before, but your script does not execute, so you
do not have to worrying about separating the output from
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
the output of your script.
There is still a lot of information in that module list that you may not want.
You probably do not care about the standard library modules, like vars
and warnings, since if Perl is installed they should be there. If you want to
see which modules outside of the standard library are used, give
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
nocore
parameter. Simply separate the parameters with a comma.
perl -d -MDevel::Modlist=stop,nocore script.pl
|
This time you get a much shorter list of modules.
HTTP::Status 1.26 LWP::Simple 1.33
|
Notice that many of the non-standard modules disappeared, too.
href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist
the shortest module name from a distribution and puts that in the list. When
you install that module, you end up installing the entire distribution.
You can also get a listing without the version numbers to easily
pipe the list into another program.
perl -d -MDevel::Modlist=stop,nocore,noversion script.pl
|
If you are creating a module that will eventually make it onto CPAN,
you can put module information in your Makefile.PL
(you should
use h2xs to
create your own
href="http://search.cpan.org/search?dist=CPAN">CPAN.pmMakefile.PL
!) and
it out. Simply tell your users to use
href="http://search.cpan.org/search?dist=CPAN">CPAN.pm
here, but you can read about it in the ExtUtils::MakeMaker
man page look for PM_PREREQS
.
However, I wrote a small script that can create the PM_PREREQS
portion of the Makefile.PL for you.
#!/usr/bin/perl while( <> ) { chomp; push @modules, ( split )[0]; } $" = "\n"; print <<"HERE"; PM_PREREQ => { @{ [ map { "\t$_ => undef," } @modules ]} }, HERE
|
If you input a list of modules, such as
HTTP::Status LWP::Simple
|
you get out an incomplete bit of code that you can put into your WriteMakefile
routine in Makefile.PL. Again, see the h2xs
man pages to see how this works.
PM_PREREQ => { HTTP::Status => undef, LWP::Simple => undef, },
|
You can extend this so that the values of the anonymous hash, which in this example
are undef, are
the version numbers of that module.
But what about your bundle? Bundles are just special modules. They live in
the Bundle
namespace (such as Bundle::MyModules
),
have a $VERSION
, and then a list of modules. Our bundle looks like
this. Put this module somewhere in Perl's @INC
search path and run the command in the SYNOPSIS section and
href="http://search.cpan.org/search?dist=CPAN">CPAN.pm
modules.
package Bundle::MyModules; $VERSION = '0.01'; 1; __END__ =head1 NAME Bundle::MyModules - What you need to use my software =head1 SYNOPSIS perl -MCPAN -e 'install Bundle::MyModules' =head1 CONTENTS HTTP::Status LWP::Simple =cut
|
You can adapt the small script that I provided earlier to create the bundle
format for you if you wish. You can also take a look at a lot of other
href="http://search.cpan.org/search?mode=module&query=Bundle">Bundles available
on CPAN
Now you can collect information on the modules that you have installed and which modules, whether core or third-party, that your script uses. You can incorporate this knowledge into your software distribution, give your users an easy way to install the right modules, and have enough time left over to catch the last episode of The Sopranos.
brian d foy has been a Perl user since
1994. He is founder of the first Perl users group, NY.pm,
and
href="http://www.perl.org">Perl Mongers
href="http://perl.stonehenge.com">Stonehenge Consulting