2008年02月22日 23:30 [Edit]

perl - モジュールと%INC

camel

うむむ、ちょっとload averageが高い日日が続いたせいか、久々に熱が。

こういう時にはこういうあまり心身を使わないネタを。

Perl モジュールのありかを調べる perlwhere - Tociyuki::Diary
モジュールのパスをてっとり早く見つけるには、コア・モジュールの Module::Build::ModuleInfo が便利です。

Module::Buildがコア入りしたのは5.10からなので、他の方法を紹介しつつ、特殊変数%INCの紹介などを。


まず、モジュールのありかを手っ取り早く調べる方法としては、

% perldoc -ml

が使える。PODが含まれてなくてもOK。

しかし、中級以上の perl monger を目指すのであれば、%INCのことも知っておきたい。

perlは一度読んだファイルをこの変数の中に押し込む。たとえばこんな感じ。

% perl -MEncode -le 'print "$_:$INC{$_}" for sort keys %INC'
Encode.pm:/usr/local/lib/perl5/5.10.0/darwin-thread-multi-2level/Encode.pm
Encode/Alias.pm:/usr/local/lib/perl5/5.10.0/darwin-thread-multi-2level/Encode/Alias.pm
Encode/Config.pm:/usr/local/lib/perl5/5.10.0/darwin-thread-multi-2level/Encode/Config.pm
Encode/Encoding.pm:/usr/local/lib/perl5/5.10.0/darwin-thread-multi-2level/Encode/Encoding.pm
Exporter.pm:/usr/local/lib/perl5/5.10.0/Exporter.pm
XSLoader.pm:/usr/local/lib/perl5/5.10.0/darwin-thread-multi-2level/XSLoader.pm
base.pm:/usr/local/lib/perl5/5.10.0/base.pm
bytes.pm:/usr/local/lib/perl5/5.10.0/bytes.pm
strict.pm:/usr/local/lib/perl5/5.10.0/strict.pm
vars.pm:/usr/local/lib/perl5/5.10.0/vars.pm
warnings.pm:/usr/local/lib/perl5/5.10.0/warnings.pm
warnings/register.pm:/usr/local/lib/perl5/5.10.0/warnings/register.pm

見てのとおり、キーはFoo::BarFoo/Bar.pmに展開したもの、そして値はそのフルパスだ。

requireuseは、このキーの存在が存在しない場合にのみ.pmを読んで実行する。これを利用すると、すでにuseしたモジュールをもう一度useすることも可能だ。

Foo.pm
package Foo;
use strict;
use warnings;

our $LOADED;
$LOADED++;

1;
use strict;
use warnings;
use Foo;

BEGIN{
    warn $Foo::LOADED;
    delete $INC{'Foo.pm'} if @ARGV;
}
{
    use Foo;
    warn $Foo::LOADED;
}
実行結果
% perl foo.pl 
1 at foo.pl line 6.
1 at foo.pl line 11.
% perl foo.pl 1
1 at foo.pl line 6.
2 at foo.pl line 11.

BEGIN{}で囲ってあることに注意。そうでないとuseの方が先に実行されてしまうので。

これを利用すると、perlwhereは以下のように書き直せる。

#!/usr/local/bin/perl
use strict;
use warnings;
for (@ARGV){
    print "$_:";
    eval qq{ require $_ };
    next if $@;
    s{::}{/}g;
    $_ .= '.pm';
    print $INC{$_}
}
continue{
    print "\n";
}
% perl perlwhere.pl Nonexistent YAML YAML::Syck JSON JSON::Syck 
Nonexistent:
YAML:/usr/local/lib/perl5/site_perl/5.10.0/YAML.pm
YAML::Syck:/usr/local/lib/perl5/site_perl/5.10.0/darwin-thread-multi-2level/YAML/Syck.pm
JSON:/usr/local/lib/perl5/site_perl/5.10.0/JSON.pm
JSON::Syck:/usr/local/lib/perl5/site_perl/5.10.0/darwin-thread-multi-2level/JSON/Syck.pm

Dan the Perl Monger

See Also:


この記事へのトラックバックURL

この記事へのトラックバック
前回の perlwhere に対して、id:dankogai さんにフォローをしていただきました。ありがとうございます。 ⇒ 404 Blog Not Found:perl - モジュールと%INC まず、モジュールのありかを手っ取り早く調べる方法としては、 % perldoc -ml が使える。PODが含まれてなくてもOK。 P
[Perl]@INC からモジュール探し【Tociyuki::Diary】at 2008年02月24日 23:49