1

I have used Module::Metadata to get a Perl module's name from its location, but it doesn't work for some modules (like DBIx::Class::Carp, DateTimePP) where the package information is missing.

use strict;
use warnings;

# Modules corresponding to Perl module information
use File::Find;
use Module::Metadata;

my @files = ();
find({
    wanted => sub {
      push @files, $File::Find::fullname
          if (defined $File::Find::fullname
        && (-f $File::Find::fullname && /\.pm$/));
    },
    follow      => 1,
    follow_skip => 2,
  },
  @INC
);

my ($file_path, $module_name, $info) = ("", "", "");
my %modules = ();

foreach $file_path (@files) {    # loop through all the perl module (.pms) found

  $info        = Module::Metadata->new_from_file($file_path);
  $module_name = $info->name;

  if (!$module_name) {
    print $file_path . "\n";
  }

  $modules{$file_path} = $module_name;
}
Borodin
  • 126,100
  • 9
  • 70
  • 144
rajesh_pg
  • 39
  • 6
  • 1
    Your two questions are beginning to smell like an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Perhaps explain what your real goal is? – Miller Aug 13 '14 at 21:39
  • @Miller I need to get all the Perl modules installed in the server and print their name and version accordingly. CGI::Apache 1.02 – rajesh_pg Aug 13 '14 at 22:45
  • 2
    [How do I get a list of installed CPAN modules?](http://stackoverflow.com/q/115425/1733163) and [How do I find out what modules are already installed on my system?](http://www.cpan.org/misc/cpan-faq.html#How_installed_modules) – Miller Aug 13 '14 at 23:02
  • Server doesn't have perldoc installed and cpan -a doesn't list user defined packages. So the above approach works for me. – rajesh_pg Aug 14 '14 at 02:10
  • 2
    `DBIx::Class::Carp` intentially tries to hide itself from parsing. The [src](https://metacpan.org/source/RIBASUSHI/DBIx-Class-0.08270/lib/DBIx/Class/Carp.pm) states this. Either way, it's installed as part of `DBIx::Class`, so it's likely not needed in your inventory anyway. As for `DateTimePP`, I can't find that module, so at minimum it's just part of `DateTime`. Either way, I suspect you have a non-problem. However, if you still want to pursue this, I suggest starting a third problem with your actual goal and explaining why your situation is unique and the refs I linked to won't work. – Miller Aug 14 '14 at 03:36
  • Ok, thanks Miller. I didn't know that DBIx::Class intentionally hides it. There are around 1107 modules in our server like DBIx::Class and DateTimePP where it hides/ doesn't display package names. As you suggest I will ask another question in a better way. – rajesh_pg Aug 14 '14 at 05:10

1 Answers1

0

Converting a (relative) perl module path to its package name is just a matter of replacing / with :: and stripping the .pm extension.

my $file_path = 'Foo/Bar.pm';
$file_path =~ s#/#::#g;
$file_path =~ s#\.pm##g;
print "$file_path\n";

Prints:

Foo::Bar

EDIT:

If you have the fully-qualified file path, you can try something like this to strip the prefix (depending on where the module is installed) and get the relative path:

use Config;
my $site_lib = $Config{sitelib};
$file_path =~ s#^$site_lib/##;
tkocmathla
  • 901
  • 11
  • 24