wu-lee has asked for the wisdom of the Perl Monks concerning the following question:

I've noticed CPANPLUS's CLI, cpanp can install WWW-Mechanize, but not Scalar-List-Utils. This seems wrong, since it ought to know that this is a valid distribution. (I chose WWW-Mechanize because it is a distribution which happens to contain a module called WWW::Mechanize; Scalar-List-Utils contains no Scalar::List::Utils module.)

$ cpanp CPANPLUS::Shell::Default -- CPAN exploration and module installation ( +v0.88) [snip] CPAN Terminal> install Scalar-List-Utils [ERROR] 'Scalar-List-Utils' does not contain an author part [ERROR] Cannot find 'Scalar-List-Utils' in the module tree No such module: Scalar-List-Utils No modules found to operate on! Nothing done

This is the latest version of CPANPLUS, v0.88.

Indeed, it cannot install PathTools (Cwd and File::Spec), libwww-perl (the LWP modules), nor perl-ldap (Net::LDAP et al.). It seems that if the distribution is not also the name of a module it includes, CPANPLUS can't find it.

The reason I ask about this is because I encountered this problem using CPANPLUS::Backend->parse_module, which has a similar problem, even though the manpage for it implies it can handle multiple forms of module names and distribution names:

parse_module tries to find a CPANPLUS::Module object that matches your + query. Here's a list of examples you could give to parse_module; Text::Bastardize Text-Bastardize Text-Bastardize-1.06 AYRNIEU/Text-Bastardize AYRNIEU/Text-Bastardize-1.06 AYRNIEU/Text-Bastardize-1.06.tar.gz http://example.com/Text-Bastardize-1.06.tar.gz file:///tmp/Text-Bastardize-1.06.tar.gz /tmp/Text-Bastardize-1.06 ./Text-Bastardize-1.06

And elsewhere:

@mods can be a list of distribution names, module names or module obje +cts, basically anything that parse_module can understand.

But parse_module fails if given Scalar-List-Utils etc. Presumably either the documentation or the implementation is wrong? How do I get a CPANPLUS::Module instance from a distribution name?

Replies are listed 'Best First'.
Re: CPANPLUS won't install distros by name (e.g. Scalar-List-Utils)
by Anonymous Monk on Nov 09, 2009 at 16:48 UTC
    I would consider it a bug, but I don't see the point in specifying dist names if you're not asking for specific versions, ie
    GBARR/Scalar-List-Utils-1.21.tar.gz
    If you don't care what version, just use module names
    Scalar::Util
      Thanks - however that doesn't really solve my problem.

      I'm trying to write a function which deduces the install sequence for a given module and its prerequisites (to feed to dh-make-perl). This function generates a list of distribution names. Unfortunately, CPANPLUS then can't install some of the distributions listed, even though it gave me the names in the first place!

      So although I could try and get the information elsewhere, or cobble the module names into the list, I'd rather just ask CPANPLUS, and I think it really ought to be able to tell me...

Re: CPANPLUS won't install distros by name (e.g. Scalar-List-Utils)
by bingos (Vicar) on Nov 10, 2009 at 15:17 UTC

    Perhaps you could have raised a RT ticket for this issue.

    Perhaps then either myself or Jos would have been able to investigate the issue. It is only because I happened to being checking perlmonks today that I spotted this.

    You hit the nail on the head, it is the distributions that have package names that are slightly unusual that parse_module has a problem with. In the vast majority of cases it can make an educated guess and get it right.

    CPANPLUS' module tree is exactly that, a tree of modules, which includes the name of the package that that module is contained in. Creating a mapping back the other way as well, ie. PACKAGE -> MODULE, is going to add more memory usage for the indexes.

    That said, there may be a way. I'm digging further.

    But please, do raise that ticket, so I don't forget.

    CPANPLUS RT Queue

    Updated:

    Found a possible solution which I will endeavour to roll into the next release. In the meantime this should work for those pesky edge-cases:

    use strict; use warnings; use CPANPLUS::Backend; my $cb = CPANPLUS::Backend->new(); my $string = shift || die; my $mod; unless ( $mod = $cb->parse_module( module => $string ) ) { ($mod) = grep { $_->package_name eq $string } $cb->search( type => 'package', allow => [ qr/^\Q$str +ing\E/ ], ); } print $mod->name, ' ', $mod->package, "\n" if $mod;

      ... it is the distributions that have package names that are slightly unusual that parse_module has a problem with. {snip}

      ... CPANPLUS' module tree is exactly that, a tree of modules, which includes the name of the package that that module is contained in.

      Just to confirm the terminology:

      • distribution -- (the tar.gz file) Ex., WWW-Mechanize-1.60.tar.gz
      • module -- (the .pm file) Ex., WWW/Mechanize/Link.pm
      • package -- Ex., WWW::Mechanize::Link
      Thanks. I was planning to submit a bug, unless it turned out I'd missed something. Done now.

      The work-around seems to do the job, too (although I can't find any way to switch off CPANPLUS's failure warnings when the first parse_module fails...)

Re: CPANPLUS won't install distros by name (e.g. Scalar-List-Utils)
by Anonymous Monk on Nov 10, 2009 at 04:20 UTC

    Nice detective work, wu-lee. Thanks.

    Personally, I would prefer to keep things logically straight and use distribution names inside cpanp, since I'm installing the whole distribution and not just a particular module from the distribution. However, everyone seems to use the package names instead, which seems confusing to me (especially since a distribution can (and often does) contain more than one package).

      Hello, anonymous, are you the author by any chance?

      I've not yet had the time to properly figure out how exactly CPANPLUS knows about package dependencies, but I think it's using 02packages.details.txt.gz (it is at least mentioned in there). Doesn't that give the required information to map a authorless and versionless distribution name to at least the most recent full distribution name?

      For now I'm using Parse::CPAN::Distributions to get the latest author and version from the bare distribution name, and giving that to CPANPLUS. (Both author and version are needed, even for the latest version.) That seems to do the trick, although it's slow to download the find-ls data.

      Perhaps CPANPLUS could do the same, either using P::C::D as I do, or by inspecting 02packages.details.txt.gz or find-ls itself?

        Sorry -- didn't mean to imply that I was the author. I'm just appreciative of your efforts here. (Gah... I really should create a proper user account here at the monastery.)

        Looking at zless ~/.cpanplus/02packages.details.txt.gz, it seems like that indeed provides the connection between package name and distribution name.