58

How can I check if a Perl module is part of the core - i.e. it is part of the standard installation?

I'm looking for:

  • a command-line command:
  • a Perl subroutine/function to check within code

Perhaps the question should be: How can I tell what modules were originally provided with the specific Perl installation on a machine? (Actually, it is now asked as How can I tell what modules were originally provided with the specific Perl installation on a machine?.)

Given that there now appears to not to be an overall Perl standard installation, at least the answer to this new question will tell me what I originally had in the installation when it was first installed.

With that knowledge and if I keep the original installer image/package OR know how to get the exact thing again online, then I have a repeatable Perl installation for several machines with the knowledge of what modules will be present and what modules will not.

To clarify further: I am looking at what came with the installation originally, what modules were provided as part of that installation, and what was built-in. NOT what has been installed since then.

And I want to be able to do this on the machine that has the installation. So for this I would be relying upon the installation to have a record in some form as to what it has originally.

I asked spin-off question: How can I tell what modules were originally provided with the specific Perl installation on a machine? (How can I tell what modules were originally provided with the specific Perl installation on a machine?)

Community
  • 1
  • 1
therobyouknow
  • 6,604
  • 13
  • 56
  • 73
  • All Debian platforms? All the same Debian release? How general do we need to be? – Greg Bacon Jan 13 '10 at 15:19
  • It doesn't matter what platform. What I'm looking for in this new question (under the heading 'update') is a general piece of code that I can use to run on a particular machine to determine what modules were originally part of the Perl installation on that particular machine. Regardless of whether it is Debian 4,5 or Ubuntu or Mandriva or whatever. – therobyouknow Jan 13 '10 at 15:42
  • 1
    When you are going to radically change a question, just ask a new one. There's not a limit to the number of questions you can ask. :) – brian d foy Jan 16 '10 at 23:18
  • @brian d foy: +1 Thanks for the encouragement: I have asked the question http://stackoverflow.com/questions/2085516/how-can-i-tell-what-modules-were-originally-provided-with-the-specific-perl-insta – therobyouknow Jan 18 '10 at 11:12

7 Answers7

65

The corelist command from the Module::CoreList module will determine if a module is Core or not.

> corelist Carp

Carp was first release with perl 5

> corelist XML::Twig

XML::Twig was not in CORE (or so I think)

Here is one way to use it in a script. The Module::CoreList POD is too terse -- you have to go hunting through the source code to find what methods to call:

use strict;
use warnings;
use Module::CoreList;

my $mod = 'Carp';
#my $mod = 'XML::Twig';
my @ms = Module::CoreList->find_modules(qr/^$mod$/);
if (@ms) {
    print "$mod in core\n";
}
else {
    print "$mod not in core\n";
}

__END__

Carp in core
toolic
  • 57,801
  • 17
  • 75
  • 117
  • 1
    Nice. I've used the CPAN shell "i" command to get info before, but corelist looks better. The "DSLIP_STATUS" for dual-lived modules doesn't seem trustworthy--some standard modules say "released" instead of "standard". For example, "i CGI" shows Stein's CPAN release (RdpOp released,developer,perl,object-oriented,Standard-Perl) even though it comes standard with Perl. – Ken Fox Jan 12 '10 at 15:19
  • 2
    Thanks but is Module::CoreList itself a core module that can be guaranteed to be present in any standard Perl installation? – therobyouknow Jan 12 '10 at 17:25
  • 3
    Module::CoreList is a core module as of 5.009002 (2005-Apr-01), according to http://perldoc.perl.org/perl592delta.html. It should be guaranteed to be part of any properly installed Perl since then, but not before. – toolic Jan 12 '10 at 17:37
  • 4
    For practical purposes, "since 5.9.2" means "since 5.10.0" for normal people :) – hobbs Jan 13 '10 at 01:42
  • 1
    Thanks for answering toolic +1 for your comment. – therobyouknow Jan 13 '10 at 09:53
  • I would like to accept your answer, toolic, but I am not able to yet as my system (Debian 4 Linux) reports the module as not found, as shown in the /var/log/apache2/error.log entry: [Wed Jan 13 10:40:23 2010] [error] [client 10.0.97.142] Can't locate Module/CoreList.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.8.8 /usr/local/share/perl/5.8.8 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.8 /usr/share/perl/5.8 /usr/local/lib/site_perl .) at /usr/lib/cgi-bin/check_dependencies.cgi line 73. It's raising an error about use Module::CoreList which is at line 73. – therobyouknow Jan 13 '10 at 10:47
  • The very fact that this fundamental module checking utility function is in a module itself is unfortunate. Ideally this should be in the true core of Perl, in early versions, as a built-in function, like print, open, close, etc. Some background about my setup: It's just a standard Debian 4 installation with all options checked during the install for scripts, web etc. The log snippet shows I am running 5.8.8 which might explain the problem, given hobbs's comment.It's a pity I have to upgrade (some places have a policy not to take upgrading lightly due to (small) risk of breaking applications). – therobyouknow Jan 13 '10 at 10:57
  • +1 for hobbs comment too for saying what version of Perl CoreList is in. If I didn't know this then I would be puzzled as to why things weren't working. Thanks. – therobyouknow Jan 13 '10 at 11:00
  • Sorry for not being able to say it works. I would like to. But I can't at the moment given the outcomes so far. Something that is checking for whether other things are core/standard or not shouldn't itself be non-core/standard. – therobyouknow Jan 13 '10 at 11:12
  • 1
    @Rob: It's still the correct answer. I think you misunderstand what that checkmark is there for. – hobbs Jan 15 '10 at 00:31
  • I'm accepting this answer. Sorry it took so long! perlmodlib looks like a good method too. But Module::CoreList is very explicit about what it is doing. Also it is clear in what Perl version this facility is available. Te be honest it should have been there at the very beginning, but only Larry Wall will have an answer for that; hindsight is wonderful thing. This is a disadvantage of Perl not being able to precisely know this answer for any version, something I believe other languages do better. – therobyouknow Jan 18 '10 at 10:49
  • I have, however, asked a spin-off question that I hope will work with any Perl version: Asked spin-off question: http://stackoverflow.com/questions/2049735 ( How can I tell what modules were originally provided with the specific Perl installation on a machine? ) – therobyouknow Jan 18 '10 at 11:16
  • 1
    link should be: http://stackoverflow.com/questions/2085516/how-can-i-tell-what-modules-were-originally-provided-with-the-specific-perl-insta – therobyouknow Jan 18 '10 at 12:32
8

You could check perlmodlib in a sub:

my %_stdmod;
sub is_standard_module {
  my($module) = @_;

  unless (keys %_stdmod) {
    chomp(my $perlmodlib = `perldoc -l perlmodlib`);
    die "cannot locate perlmodlib\n" unless $perlmodlib;

    open my $fh, "<", $perlmodlib
      or die "$0: open $perlmodlib: $!\n";

    while (<$fh>) {
      next unless /^=head\d\s+Pragmatic\s+Modules/ ..
                  /^=head\d\s+CPAN/;

      if (/^=item\s+(\w+(::\w+)*)/) {
        ++$_stdmod{ lc $1 };
      }
    }
  }

  exists $_stdmod{ lc $module } ? $module : ();
}

Example usage:

die "Usage: $0 module..\n" unless @ARGV;

foreach my $mod (@ARGV) {
  my $stdmod = is_standard_module $mod;
  print "$0: $mod is ", ($stdmod ? "" : "not "), "standard\n";
}

Output:

$ ./isstdmod threads::shared AnyDBM_File CGI LWP::Simple
./isstdmod: threads::shared is standard
./isstdmod: AnyDBM_File is standard
./isstdmod: CGI is standard
./isstdmod: LWP::Simple is not standard

perldoc is most definitely part of the Perl's true core and standard installation. The source distribution for perl-5.10.1, for example, contains

  • perldoc.PL, generates perldoc as part of the standard installation
  • perlmodlib.PL, generates perlmodlib.pod as part of the standard installation

This is not a new addition. Perl-5.6.0, about ten years old, had perlmodlib as part of its true-core, standard installation.

Installations that do not contain these items are non-standard. Yes, I appreciate that it may seem academic from your perspective, but your vendor's packaging permitted a non-standard installation that breaks otherwise working programs.

With Debian's package manager, you can get the standard Perl installation with

$ apt-get --install-recommends install perl
Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
  • This answer looks more favourable than Module::CoreList because I'm assuming that perlmodlib is available as core/standard in earlier Perl versions where Module::CoreList is not available. – therobyouknow Jan 13 '10 at 11:03
  • Update: Got error in my Debian 4 Linux /var/log/apache2/error.log log: [Wed Jan 13 11:05:15 2010] [error] [client 10.0.97.142] You need to install the perl-doc package to use this program. [Wed Jan 13 11:05:15 2010] [error] [client 10.0.97.142] cannot locate perlmodlib So I *have* to install something to get this to work! Again ditto my comments for toolic's answer: "Ideally this should be in the true core of Perl, in early versions, as a built-in function, like print, open, close, etc." = – therobyouknow Jan 13 '10 at 11:10
  • To add to this: Something that is checking for whether other things are core/standard or not shouldn't itself be non-core/standard. – therobyouknow Jan 13 '10 at 11:10
  • Sorry for not being able to say it works. I would like to. But I can't at the moment given the outcomes so far. – therobyouknow Jan 13 '10 at 11:11
  • gbacon, see what "brian d foy" says below about "standard installation" - apparently this does not exist. Certainly, I've done nothing special with my Perl install that came with Debian 4. Maybe Debian 5 improves on it but I can't assume all the machines I want to use this for will have that. – therobyouknow Jan 13 '10 at 14:57
  • Also, see my update about a suggested re-write of the question: "how do I work out what came with a particular installation". – therobyouknow Jan 13 '10 at 15:13
  • 1
    Perl's source tells us what's in the standard installation. That is beyond dispute, so let's move on to a more relevant question: what are you ultimately trying to do? – Greg Bacon Jan 13 '10 at 15:13
  • Fine. So how can I query what's in an installation on a particular machine? I've explained what I am ultimately trying to do in the Update to the original question. – therobyouknow Jan 13 '10 at 15:45
  • @gbacon: without getting into heavy semantics, Debian's `perl` package is separate from its `perl-doc`. I think this is a mistake on Debian's part, but that doesn't change the facts. The `perl-doc` package is considered 'suggested'. On a standard Debian machine, packages marked as 'recommended' will automatically be installed, but 'suggested' packages will not. So, passing `--install-recommends` won't help. It's also pointless in general, since installing recommended packages is itself the Debian default. Details of Debian's `perl` package here: http://packages.debian.org/lenny/perl – Telemachus Jan 16 '10 at 21:51
  • Argh! With etch, `perl-doc` was recommended: http://packages.debian.org/etch/perl – Greg Bacon Jan 16 '10 at 22:18
  • Thank you folks for all your effort answering here with some very good points. I've accepted Module::CoreList as this facility is specific to what I am trying to achieve. It is not perfect though as it is only supported in later versions when it should be in everything. – therobyouknow Jan 18 '10 at 10:51
7

There really is no such thing as "core" any more. There used to be a standard Perl distribution, but a lot of people don't have a standard Perl distribution. Operating system distributions modify it by either adding or removing modules, changing modules, and so on. You can't rely on the standard distribution being actually standard. Some Linux distributions don't even include the Perl documentation as part of the base Perl installation.

You mention that you can't use Module::CoreList because it isn't core, but if you can create files, you can install the module. You can even pretend that you wrote it yourself.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • Thanks +1. From the useful feedback from yourself and others I am beginning to conclude that there isn't a black and white simple answer to my question. I will have to tolerate that and work around it or ask a better question. – therobyouknow Jan 13 '10 at 14:49
  • It's not really a case of can't use Module::CoreList it's more the case that I would strongly prefer not to if I can avoid it. I wanted to see if there was a built-in feature and was guaranteed to be present in every Perl installation, like keywords print, open, etc. are. This now appears unlikely. Ideally I would prefer not to have to change the state of the system (i.e. by installing the Module::CoreList) that I am checking core modules for. I don't want to change what I am measuring. – therobyouknow Jan 13 '10 at 14:52
  • Certainly also agree that I can't "rely on the standard distribution being actually standard" and that "some linux distributions don't even include the Perl documentation as part of the base Perl installation": My Debian 4 distribution is nothing special, just the straight forward Debian install, which meant I couldn't try out the perlmodlib solution suggested here by another poster. – therobyouknow Jan 13 '10 at 14:55
  • 1
    If you are writing programs, you are changing the state. Module::CoreList is just code. It doesn't really matter who wrote it. – brian d foy Jan 13 '10 at 14:56
  • Also, see my update about a suggested re-write of the question: "how do I work out what came with a particular installation". – therobyouknow Jan 13 '10 at 15:14
  • 1
    That really should have been a new question. – brian d foy Jan 16 '10 at 23:17
3

For the really lazy, there's the Core Modules list on the perldoc.perl.org website.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • 1
    This answer satisfies neither requirement. It's not even the simplest thing that could work. – brian d foy Jan 13 '10 at 14:13
  • 1
    @brian d foy: Yes, I deliberately ignored those requirements because they were unnecessary. Now that the question has been updated, this answer still stands, because it still gives you a reasonable expectation of what modules *should* be in a default perl install without requiring extra modules to be installed. – Powerlord Jan 13 '10 at 17:59
  • +1 @R. Bemrose: I definitely agree that it is a "reasonable expectation"! I may post the updated question as a separate to give more visibility as it is different enough to benefit from some additional posters' answers. – therobyouknow Jan 16 '10 at 13:00
2

You can use (for example, search for Net::FTP):

perl -MNet::FTP -e 1

If it doesn't have output, then it's installed.

Other resources

perldoc perlmodlib 
perldoc perllocal

A node from perlmonks

Community
  • 1
  • 1
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
0

In a response to a comment of Gbacon's, you say that you want the answer to be platform neutral. I don't know of such a solution, but I wonder if it's even the right way to go.

If your goal is to find out on specific machines, I would use the tools that come with the platform. On Debian, that would include dpkg (pre-installed on any Debian system) or apt-file (not pre-installed necessarily) or other APT tools.

As an example, take a look at the output of this:

dpkg-query -L perl | less

You would obviously need to parse the output, but it strikes me as a start precisely because it is specific to the machine in question.

Telemachus
  • 19,459
  • 7
  • 57
  • 79
-1
  • From the command-line:

    Let's say that you want to know whether module Tie::Hash is installed.
    To find out, execute the following from the command line:

    perl -MTie::Hash -e 1
    

    If you don't get any output from the above command then the module is installed; if you get an error, it's not installed.

  • For making this check from within the script you can make use of Module::Load::Conditional.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
codaddict
  • 445,704
  • 82
  • 492
  • 529
  • 3
    Keep in mind that these methods do not distinguish between Core modules and non-Core modules, as defined by perlmodlib. These methods will check for all installed modules. – toolic Jan 12 '10 at 15:28