pmtools

Journal of Mark Leighton Fisher (4252) で Tom Christiansen が 1999 年に書いた pmtools なるツール群があるという話が挙がってました。pmtools という名前を初めて聞いたもんで、試しにインストールしてみました。

pmtools は Perl のモジュールや POD に関する小さなコマンドラインツールがいろいろ同梱されてるパッケージです。インストールはアーカイブ落としてきて perl Makefile.PL; make; sudo make install で OK。それぞれのコマンドの使い方は README 見るなり man 見るなりで見ることができます。

基本的に Perl のコード数行からなる簡易ツールで、ワンライナーとかでやることが多いものをコマンドひとつで呼べるようにしてるとか、そういうものがほとんどでした。1999年と古いツールなので、今となっては使いどころが微妙というものも多いのですが、いくつか便利そうな物がありました。

以下、何をするものだとか、使ってみての感想。

pmpath
モジュールのパスを表示。まあこれは perldoc -l でも問題ない。
pmvers
モジュールのバージョンを表示。これは便利。perl -MCGI -e 'print CGI->VERSION, "?n"' とかしてたのタイプ量が減る。
pmdesc
モジュールの description を表示。どんなモジュールかちょっとみたいというときに使う...perldoc でいい気がするな。
pmall
インストール済みモジュール一覧を description と一緒に表示。すごい数表示されたw
pmdirs
モジュールのパス(ディレクトリ)を表示。どうかなあ。
plxload
"show what files a given program loads at compile time" これは便利!...と思ったけどコマンドラインツール対象ぐらいにしか使えないかも。中で使われてる Devel::Loaded に興味がわいた。→ ただ %INC dump してるだけだったw
pmload
"show what files a given module loads at compile time" こっちは便利。これもスクリプト中ではたいしたことしてないけど、コマンド一個ですぐに結果がみれるのがいい。
pmexp
"show a module's exports" ... 何のタグを使うと何がインポートされるかという一覧が見れる、結構便利だ。
pminst
インストールされてるモジュール名を任意のワードで検索。引数で正規表現が使える。これはいいよ。
pmeth
指定したクラスに定義されてるメソッドを一覧表示。便利と言えば便利。
pmls
ls -l `pmpath CGI`的な。微妙。
pmcat
指定したモジュールのソースコードをみる。perldoc -m でいいや。podstrip してくれてたら嬉しかったけど。
pman
モジュールの pod をみる。perldoc で良い。なんでこのコマンドを作ったのかな。1999年の perlodc は今とは違ってたんだろか。
pmfunc
指定した関数のコードをみる。これは良い。
podgrep
pod に対して grep をかける。使いどころがありそうで微妙。
pfcat
"show pods from perlfunc" だけどちゃんと動かないな。
podtoc
pod から TOC 作って表示。TOC が欲しいときは search.cpan.org 見るから必要なさそう。

残りは pod に関するツールがいくつか。

使いそうなのは、

  • pmvers
  • pmload
  • pmexp
  • pminst
  • pmfunc

あたりですか。コマンド名覚えるのがめんどくさいけど、pm* で補完すれば良さそう。便利そうなやつの出力はこんな感じ。

$ pmvers mod_perl2
2.000002

$ pmload URI
/usr/local/lib/perl5/5.8.7/Carp.pm
/usr/local/lib/perl5/5.8.7/warnings/register.pm
/usr/local/lib/perl5/site_perl/5.8.7/URI.pm
/usr/local/lib/perl5/5.8.7/Exporter.pm
/usr/local/lib/perl5/5.8.7/vars.pm
/usr/local/lib/perl5/5.8.7/strict.pm
/usr/local/lib/perl5/5.8.7/warnings.pm
/usr/local/lib/perl5/5.8.7/overload.pm
/usr/local/lib/perl5/site_perl/5.8.7/URI/Escape.pm

$ pmexp IO::Handle
IO::Handle optionally exports autoflush, output_field_separator...

$ pminst '^Apache2'
Apache2::Access
Apache2::Build
Apache2::BuildConfig
Apache2::CmdParms
...

$ pmfunc Class::Data::Inheritable::mk_classdata
sub mk_classdata {
    my ($declaredclass, $attribute, $data) = @_;

    if( ref $declaredclass ) {
        require Carp;
        Carp::croak("mk_classdata() is a class method, not an object method");
    }

    my $accessor = sub {
        my $wantclass = ref($_[0]) || $_[0];

        return $wantclass->mk_classdata($attribute)->(@_)
          if @_>1 && $wantclass ne $declaredclass;

        $data = $_[1] if @_>1;
        return $data;
    };

    my $alias = "_${attribute}_accessor";
    *{$declaredclass.'::'.$attribute} = $accessor;
    *{$declaredclass.'::'.$alias}     = $accessor;
}

たまには古いツールを漁ってみるということも必要そうです。

しかしまあ 1999 年に書かれた Perl スクリプトが最新版の 5.8.7 で全く問題なく動くという、Perl後方互換性考慮には脱帽ですな。