21
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

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

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
21
Help us understand the problem. What are the problem?