App::RadというCLIがだいぶ良い
App::Rad というコマンドラインツールがあるのですが、
手軽にサブコマンド作れてだいぶウマーな感じなのに
日本語情報が全くないので紹介してみます。
基本系
まずは「rad.pl」に「bucho」というサブコマンドを作ってみたいと思います。
use App::Rad; App::Rad->run; sub bucho { return "Hello Bucho!"; }
たったこれだけです。まずは実行してみましょう。
$ perl rad.pl Usage: rad.pl command [arguments] Available Commands: bucho help show syntax and available commands
いい感じにヘルプが出ました。
定義したサブルーチン「bucho」が勝手にサブコマンドとして認識されていますね。
buchoコマンドを実行してみましょう。
$ perl rad.pl bucho Hello Bucho!
実行されました。簡単!
help
buchoコマンドもヘルプに出したいですよね。
こんな感じで書いてみましょう。
use App::Rad; App::Rad->run; sub bucho :Help(give a nice compliment) { return "Hello Bucho!"; }
変な構文ですね。ヘルプを実行してみましょう。
$ perl rad.pl Usage: rad.pl command [arguments] Available Commands: bucho give a nice compliment help show syntax and available commands
ヘルプがついた!
setup
setupコマンドはスクリプトの初期化処理のようなものです。
いくつか例を挙げてみましょう。
以下は先ほどのbuchoコマンドを定義したものです。
sub setup { my $c = shift; $c->register_commands( { bucho => 'give a nice compliment!', }); }
もちろん、ここに書いておけば:Helpみたいな変な構文もいりません。
また、サブルーチン全てがコマンドとして登録したくないこともあるでしょう。
その時にはこのように明示的に指定するのが良いでしょう。
逆に、コマンドとして認識させない、という設定もあります。
以下は「_」で始まるサブルーチンをコマンドとして登録させません。
sub setup { my $c = shift; $c->register_commands( { -ignore_prefix => '_' } ); }
ただし、コマンド管理については
最初に紹介した「使うコマンドを登録する」方式がオススメです。
なぜならuseしたときにExportされるサブルーチンも自動で登録されてしまうため、
除外方式だとカバーしきれなくなってくるからです。*1
ちなみにコマンドを削除する「unregister_command 」
というサブルーチンもあったりします。
引数/バリデーション
引数を扱うにはoptionsを使います*2。
$ perl rad.pl create --id=aaa ... sub create { my $c = shift; print $c->options->{id}, "\n"; # aaa }
バリデーションを行いたい場合、getoptを使う方法と
自前でチェックする方法が考えられます。
お好みでどうぞ。
# getopt sub create { my $c = shift; $c->getopt( 'id=s', 'version=i' ) or $c->execute('usage') or return undef; } # Data::Validator sub create { my $c = shift; my $args = eval { state $rule = Data::Validator->new( account_id => { isa => 'Str'}, ); $rule->validate($c->options); }; if($@) { $c->execute('usage') or return undef; } }
共有データ
stashを使うと変数を共有できます。
use Redis::hiredis; sub setup { my $c = shift; my $redis = Redis::hiredis->new(); $redis->connect('127.0.0.1', 6379); # stashに入れる $c->stash->{redis} = $redis; } sub create { my $c = shift; … # stashから取り出す $c->stash->{redis}->command('set foo bar'); }
他の便利メソッド
pre_processやpost_processもとても便利ですが
デフォルトの動作が変わってしまう可能性があるので
気をつけて使う必要があるでしょう。*3
example
DynamoDBを操作する簡易CRUDコマンドを作ってみます。
# 例1:createサブコマンド実行 perl dynamodb_crud.pl create --id=1 --name=tori
簡易デプロイツールのテンプレのようなもの。
# 例1:deployサブコマンドをdevelopmentモードで実行 perl deploy.pl deploy --env=development
その他注意点
デフォルトではサブコマンドの戻り値が標準出力されるため、*4
何も出力したくない場合はいちいち
return undef;
しないといけません。
最後に
今までコマンドラインツールといえばGetopt::Longでしたが、
簡単なスクリプトならお手軽にかけますし
Getopt::Longの代わりとしてもアリなのではないでしょうか。
defaultメソッドに処理を書けばサブコマンドなしでも動きますし。*5
use App::Rad; App::Rad->run(); sub default { rand(10) }
紹介しきれなかった機能もたくさんあるので
ドキュメントをご参照ください。
http://search.cpan.org/~garu/App-Rad-1.04/lib/App/Rad.pm