Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Tracking Perl Module Use


Perl's All Mod Cons

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, a module by Andreas

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 module in

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 may need

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 module has a function

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 stores the list of

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 can use bundles to

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 to install the modules

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. This

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 debugger

with the

href="http://www.perldoc.com/perl5.6/pod/perlrun.html">-d switch to perl.

	



	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 debugger,

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 special

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 switch to activate

the debugger, but you have to use the

href="http://www.perldoc.com/perl5.6/pod/perlrun.html">-M switch to include

the

href="http://search.cpan.org/search?dist=Devel-Modlist">Devel::Modlist module

since

href="http://www.perldoc.com/perl5.6/pod/perlrun.html">-M allows you to pass

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 from

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 the

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 takes

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 Makefile.PL!) and

href="http://search.cpan.org/search?dist=CPAN">CPAN.pm will magically figure

it out. Simply tell your users to use

href="http://search.cpan.org/search?dist=CPAN">CPAN.pm . I am covering it

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

and ExtUtils::MakeMaker

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 will install those

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, the Perl advocacy organization. He has been teaching Perl through

href="http://perl.stonehenge.com">Stonehenge Consulting for the past three years, and has been a featured speaker at The Perl Conference, Perl University, YAPC, COMDEX, and Builder.com. Some of brian's other articles have appeared in The Perl Journal.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.