CLI::Dispatch 0.01

というのを書いた。基本的な使い方はApp::CLI(や、ユーザレベルではApp::Cmd)とほとんど同じで、ディスパッチャとなるスクリプトにコマンド名(と、必要なら追加の引数やオプション)を渡してやると、そのコマンドが実行される、というシロモノ。
具体例をあげると、こんな感じのコマンド(lib/MyScript/ConvertMe.pm)と、

package MyScript::ConvertMe;

use strict;
use warnings;
use base qw( CLI::Dispatch::Command );
use Encode;

sub options {qw( from|encode=s to|decode=s )}

sub run {
  my ($self, @args) = @_;

  unless (@args) {
    $self->logger(1) unless $self->logger;
    $self->log( warn => "USAGE: convert_me <strings> --from=<encoding> --to=<encoding>" );
    return;
  }

  my $text = join ' ', @args;
     $text = decode( $self->option('from') || 'utf8', $text );
     $text = encode( $self->option('to')   || 'utf8', $text );
  print $text;
}
1;

__END__

=head1 NAME

MyScript::ConvertMe - convert me

=head1 DESCRIPTION

blah blah blah

こんなスクリプト(script.pl)をひとつ用意して、

#!/usr/bin/perl

use strict;
use warnings;
use lib 'lib';
use CLI::Dispatch;

CLI::Dispatch->run('MyScript');

シェル/コマンドラインから

 > perl script.pl convert_me ほげほげ --from=shiftjis --to=utf-8

を実行すると、(「ほげほげ」が正しくshiftjisだったら)「ほげほげ」をutf-8に変換した文字列が表示される、という寸法。

これだけだったら素のスクリプトを書いた方が早そうなもんですが、

 > perl script.pl

convert_me - convert me
help       - show help

という(その時点で利用可能な)コマンド一覧が短い説明とともに表示されたり、

 > perl script.pl help convert_me

でMyScript::ConvertMeのPODが表示されたりする、というのがこの手のツールの特徴。

こういう形でスクリプト/コマンドを管理していくと、コマンドのテストが書きやすくなるとか、podを書きたくなるとか、依存モジュールの管理がしやすくなるとか、スクリプトの再利用が楽になるとかいう利点があるよ、というのは今年のYAPCで話した通り。

変わったところでは、lib/MyScript/Help.pmをこんな風にしておいて

package MyScript::Help;

use strict;
use warnings;
use base qw( CLI::Dispatch::Help );

sub options {qw( from|encode=s to|decode=s lang=s )}

sub extra_namespaces {
  my $self = shift;
  my $lang = uc($self->option('lang')) || 'EN';
  return (
    'MyScript::Manual::'.$lang,
    'MyScript::Manual::EN',
  );
}

1;

lib/MyScript/Manual/EN/Install.podとかlib/MyScript/Manual/JA/Install.podとか用意してやると、

 > perl script.pl help install --lang=ja

でマニュアルの言語を切り替えられるようになったりします。

そのほかの使い方についてはPODとテスト参照ということで。