先日の当サイトの検索キーワードにこんなものが引っかかっていた。
- perl+モジュールのバージョン一覧取得
- perl+モジュールのバージョン
- perl+モジュールのバージョンを調べる
よくあるお題だけど、残念ながらまだそんな記事は書いていないのできっとこの人はお目当ての記事は見つけられなかったと思うな。
で、そう言えば実際にはどんなコードを書けばいいんだっけ?と調べてみると、けっこう方法がたくさん有る。せっかくなのでまとめてみました。
そもそも"何の"モジュールのバージョンを調べるのか?
一口にモジュールのバージョンと言っても沢山考えられますね。
- 実行中のパッケージで読み込んでいるモジュールのバージョン一覧
- インストールされているモジュールのバージョン一覧
- 標準モジュールのバージョン一覧
今回は一つ目のパターンを検証してみます。
実行中のパッケージで読み込んでいるモジュールのバージョン一覧
あるパッケージの中で使われているモジュール(requireやuseされている、という意味で)は、%INCという特殊変数に格納されています。
例えばこんなコードで一覧を出す事ができます(module_list.pl )。
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Encode;
use File::Spec;
print "$_\n" for (keys %INC);
Mac OS X Snow Leopard上で、Perl 5.12.2を使って実行すると、こんな結果が出ました。意外と直接していないモジュールも実は呼び出されている事が分かりますね。
$ perl module_list.pl
bytes.pm
warnings/register.pm
XSLoader.pm
File/Spec/Unix.pm
Encode/Alias.pm
Exporter.pm
vars.pm
strict.pm
Encode/Config.pm
Encode/Encoding.pm
warnings.pm
File/Spec.pm
utf8.pm
Encode.pm
base.pm
@INCで設定されているモジュールの読み込みパス以降のファイル名が表示されています(ちなみにハッシュ値の方には@INCのパスも含めたフルパスが入っています)。
%INCはパッケージ毎に定義されているので、上記の出力はmainパッケージで読み込まれているモジュールの一覧になります。別のパッケージを定義して、別のモジュール呼び出しを行うと、異なる結果が表示されます。
モジュールのパス名が分かったので、後はパッケージ名形式に変換して、$VERSIONを取得すれば、バージョン一覧が取得できます。
こんなコードを書いて見ました(module_list2.pl)
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Encode;
use File::Spec;
no strict 'refs';
foreach my $module (sort keys %INC) {
$module =~ s/\//::/;
$module =~ s/.pm$//;
if (defined ${$module . "::VERSION"}) {
print "$module\t" . ${$module . "::VERSION"} . "\n"
}
}
$ perl module_list2.pl
Encode 2.40
Encode::Alias 2.12
Encode::Config 2.05
Encode::Encoding 2.05
Exporter 5.64_01
File::Spec 3.3101
XSLoader 0.10
base 2.15
bytes 1.04
strict 1.04
utf8 1.08
vars 1.01
warnings 1.09
warnings::register 1.01
バージョンが定義されていないパッケージもあるので、数が一致していませんが、これで現在パッケージで使っているモジュールのバージョン一覧が取得できました。
次回は「インストールされているモジュールのバージョン一覧」をやってみます。