Perl

インストール済みのモジュール一覧を得る方法

More than 5 years have passed since last update.

簡単に書くと以下のようなかんじ。


collect-modules.pl

#!/usr/bin/env perl

use strict;
use warnings;

use File::Find;
use File::Spec;

my %modules = ();
my %inc = map { $_ => $_ } map { File::Spec->canonpath($_) } grep { -d $_ && $_ ne '.' } @INC;

for my $path (keys %inc) {
find(+{
wanted => sub {
my $name = $File::Find::fullname;
if (-d $name) {
if (exists $inc{$name} && $inc{$name} ne $path) {
$File::Find::prune = 1;
}
return;
}
return unless $name =~ s/\.pm\z//;

$name = File::Spec->abs2rel($name, $path);
my $module = join('::', File::Spec->splitdir($name));
$modules{$module}++;
},
follow => 1,
follow_skip => 2,
}, $path);
}
print "$_\n" for sort keys %modules;


@INC以下(カレントディレクトリは除外)をFile::Find::findでフルパス探索し、


  • 拡張子で*.pmなファイルのみ抽出


  • @INCの別要素に含まれているディレクトリ以下は探索を打ち切る



    • $Config{archname}以下のものなど複数のpath起点で抽出されるのを防ぐため




  • File::Spec->abs2relを使って抽出されたファイルの相対パスを取得


  • /::に置換

することで得られる。

helm-perldocではこの方式でモジュール一覧を取得している。


参照

cpan -lFile::Find::findを使って@INC以下の*.pmファイルのパスを取得した後、若干強引にモジュール名に変換している。cpan -aはCPAN Indexからモジュール一覧を取得して その中からインストール済みのものをリストアップする、という方式。

ExtUtils::Installedを使うとインストール済みの"ディストリビューション名"の一覧を取るには便利。ただし各ディストリビューションに含まれるモジュール一覧までは取得できない。