The hard way to install modules is to download them off of CPAN with
your web browser, uncompress them, run the Makefile.PL (and do the
same for any prerequisite modules that script complains about that are
missing) then run the make file to build the module, then make test
to test it and finally run make install to install the module.

While that works, I'm not a big fan of going to going to such lengths
needlessly. Especially when I can just use the CPAN shell to
install a module (including all the modules that that module needs
itself to function) with one command.

Having lauded CPAN, there's a new installation tool on the block.
CPANPLUS.

So what's the difference? Well, to be honest, from a user point of
view, not much - well, nothing significant anyhow. The real difference
is in the backend. You see, CPANPLUS was designed from the outset
to be used programatically instead of just interactively. This means
you can write scripts to do automatic module installation for you
easily. Indeed, yesterday's module Acme::Intraweb was written
using CPANPLUS. But more than that, you can apply intelligence to
querying CPAN for you - for the first time you as a user can turn the
power of Perl on the Centralised Peal Archive Network itself.

The syntax is a little different to CPAN.pm, and it's got a few good
extra features. For example, it's able to interact with the CPAN
Testers system allowing you to report if installations were successful
on your system and query the existing database of other user's attempts
to install the module.

Now, how about using it programatically? Let's write a simple script
to get a list of modules that are currently installed on my system.

The $backend->installed returns a CPANPLUS::Backend::RV
object. These 'Result Values' are used thoughtout the
CPANPLUS::Backend api to represent the results of a query. They can
be integrated to see if a query was successful or not (we can check it
with the ok method.) They also hold the results for that query and
provide us a way of getting the data back again (with the rv
method.) Dependant on the type of query we did the result value may
also support many other methods. In this case we simply get the
results back which is a hashref of the locations of the modules that
are installed keyed by their name. We then took the keys of this hash
(the module names) and placed them in a list, as that's all we're
really interested in at the moment - a list of the names of the
modules installed on the system.

So, what can we use this list of modules for? Well, I find that if I've
installed a module then it's often worth looking at the other modules
that that person has written to see if they're useful too. So, let's
write a script to find out who wrote each of the modules we have installed
already, and who's written the most.

Before we get ahead of ourselves, we first need to get the module
object for each of the modules that we have rather than just the name
of the modules. CPANPLUS::Backend has the module_tree method
that we can ask for hashref that contains a module object for each
module that's ever been uploaded to the CPAN keyed by name. We want
to produce a similar hash, but just with the objects that represent
the modules we've installed in it.

# get the module tree
my $tree = $backend->module_tree();

# get the object for each of the installed modules
# i.e. build a module tree for just the installed modules
my %installed_module_objs;
foreach my $module (@installed)
{
# get the object from the tree for that module
$installed_module_objs{ $module } = $tree->{ $module };
}

Now what we need to do is work our way though that hash and count
how many modules each author did.

Note that this %authors hash contains the number of modules, not
the number of distributions, each author uploaded to CPAN. People
like ABW are going to have a large number of modules since just
installing something like the Template Toolkit will install seventy or
so little modules. Still, understanding the limitations of this, we
still sort the modules:

# create a sorted list of authors,
my @sorted = sort {

# those with the largest number of modules first
$authors{ $b } <=> $authors{ $a }

# and for those with the same number of modules
# then sorted alphabetically
or $a cmp $b

} keys %authors;

And finally we can create a little HTML page that lists all those
modules.

# and finally print that out

# open the file
use IO::File;
my $fh = IO::File->new("authors.html",">")
or die "Can't open 'authors.html': $!";