LoginSignup
0
1

More than 5 years have passed since last update.

コマンド引数の処理を楽にする

Posted at

コマンド引数の処理を楽にする

みなさんPerl書いてますか?

今回は、「コマンド引数の処理を楽にする」モジュールをご紹介します。

使用するモジュールは、Getopt::Kingpinです。

Getopt::Kingpin

入ってない方は、cpanm -v Getopt::Kingpinでインスコしましょう。

便利なこと

このモジュールを使うと下記の様な処理が楽にできます。

  • フラグ・引数の定義
    • ショートフラグの設定
    • 値の形式をチェック(string, int)
    • 必須項目の設定
    • デフォルト値の設定
    • 指定ファイルの有無チェック
    • サブコマンドの設定
  • --helpの自動生成

などなど・・・

すべては紹介できませんが、よく使うものを中心にご紹介していきます。

フラグ・引数の定義

まずは、フラグと引数の定義からやってみましょう。

フラグ「piyo」と引数「fuga」を定義したプログラムを用意します。

hoge.pl
use strict;
use warnings;
use utf8;

use Getopt::Kingpin;

my $kingpin = Getopt::Kingpin->new;

# フラグ(flag)の定義
my $piyo = $kingpin->flag('piyo', 'piyo desu')->string;

# 引数(arg)の定義
my $fuga = $kingpin->arg('fuga', 'fuga desu')->string;

# フラグ・引数を解析
my $cmd = $kingpin->parse;

# 値を取得
printf "flag: %s\n", $piyo->value;
printf "arg : %s\n", $fuga->value;

フラグと引数を指定してプログラムを実行すると・・・

$ perl hoge.pl --piyo aaa bbb
flag: aaa
arg : bbb

取得できました。

ショートフラグの設定

ショートフラグの設定も簡単です。

flagで定義したものに対してshort('x')を指定するだけ!

flag('xxx', 'xxxxx')->short('x')->string;

先程の--piyo-pでも処理できるようにすると

my $piyo = $kingpin->flag('piyo', 'piyo desu')->short('p')->string;

こんな感じですね。

$ perl hoge.pl --p aaa bbb
flag: aaa
arg : bbb
$ perl hoge.pl --piyo aaa bbb
flag: aaa
arg : bbb

上記のどちらでも同じ指定したことになります。

値の形式をチェック

値の形式を指定することもできます。

# フラグ
flag('xxx', 'xxxxx')->string;
flag('xxx', 'xxxxx')->int;

# 引数
arg('xxx', 'xxxxx')->string;
arg('xxx', 'xxxxx')->int;

フラグ・引数を解析するときに、指定した形式かチェックしてくれます。

先程のコードを変更して、フラグと引数を「string」→「int」に変更して試してみましょう。

hoge.pl
use strict;
use warnings;
use utf8;

use Getopt::Kingpin;

my $kingpin = Getopt::Kingpin->new;

# フラグ(flag)の定義
my $piyo = $kingpin->flag('piyo', 'piyo desu')->int;

# 引数(arg)の定義
my $fuga = $kingpin->arg('fuga', 'fuga desu')->int;

# フラグ・引数を解析
my $cmd = $kingpin->parse;
$ hoge.pl --piyo aaa bbb
int parse error

必須項目の設定

必ず指定してほしいフラグ・引数には、required()を設定すると指定しなかったらエラーとなり処理を止めることができます。

hoge.pl
use strict;
use warnings;
use utf8;

use Getopt::Kingpin;

my $kingpin = Getopt::Kingpin->new;

# フラグ(flag)の定義
my $piyo = $kingpin->flag('piyo', 'piyo desu')->required->string;

# 引数(arg)の定義
my $fuga = $kingpin->arg('fuga', 'fuga desu')->required->string;

# フラグ・引数を解析
my $cmd = $kingpin->parse;

--piyo(required)を指定しなかった場合

$ hoge.pl bbb
hoge.pl: error: required flag --piyo not provided, try --help

デフォルト値の設定

デフォルト値の設定も簡単です。

default('xxx')を使用します。

# フラグ
flag('xxx', 'xxxxx')->default('aaa')->string;

# 引数
arg('xxx', 'xxxxx')->default('bbb')->string;
hoge.pl
use strict;
use warnings;
use utf8;

use Getopt::Kingpin;

my $kingpin = Getopt::Kingpin->new;

# フラグ(flag)の定義
my $piyo = $kingpin->flag('piyo', 'piyo desu')->default('piyopiyo')->string;

# 引数(arg)の定義
my $fuga = $kingpin->arg('fuga', 'fuga desu')->default('fugafuga')->string;

# フラグ・引数を解析
my $cmd = $kingpin->parse;

# 値を取得
printf "flag: %s\n", $piyo->value;
printf "arg : %s\n", $fuga->value;

実行時、何も指定してなかったらデフォルト値が使用されます。

$ perl hoge.pl
flag: piyopiyo
arg : fugafuga

指定ファイルの有無チェック

ファイルやディレクトリを指定するようにした場合、エラーチェックを書かなければいけませんよね。

それもGetopt::Kingpinに任せちゃいましょう。

下記のような関数が用意されています。

  • existing_file
    • 存在するファイル
  • existing_dir
    • 存在するディレクトリ

上記の形式としてフラグ・引数を指定した場合は、

解析時にファイル・ディレクトリの存在有無をチェックしてくれます。

ちなみにvalue()Path::Tinyな形で返してくれるので、

あとは煮るなり焼くなりは好きにできますね。

hoge.pl
use strict;
use warnings;
use utf8;

use Getopt::Kingpin;

my $kingpin = Getopt::Kingpin->new;

# フラグ(flag)の定義
my $piyo = $kingpin->flag('piyo', 'piyo desu')->existing_file;

# 引数(arg)の定義
my $fuga = $kingpin->arg('fuga', 'fuga desu')->existing_dir;

# フラグ・引数を解析
my $cmd = $kingpin->parse;

my $piyo_file = $piyo->value;
my $fuga_dir = $fuga->value;
piyo.txtがないとき
$ perl hoge.pl --piyo piyo.txt fuga_dir
error: path 'piyo.txt' does not exist, try --help
fuga_dirがないとき
$ perl hoge.pl --piyo piyo.txt fuga_dir
error: path 'fuga_dir' does not exist, try --help

存在しないファイルを指定したい場合は、file()を使用できます。
こちらもPath::Tinyな形で返してくれます。

flag('xxx', 'xxxxx')->file

サブコマンドの設定

サブコマンドの設定も簡単です。

Getopt::Kingpinオブジェクトに対して、command()を使用します。

サブコマンドのフラグ・引数の定義に関しても、同じように定義していくだけです。

hoge.pl
use strict;
use warnings;
use utf8;

use Getopt::Kingpin;

my $kingpin = Getopt::Kingpin->new;

# サブコマンド「aaa」
my $aaa = $kingpin->command('aaa', 'aaa command desu');

# サブコマンド「aaa」 - フラグ(flag)の定義
my $piyo = $aaa->flag('piyo', 'piyo desu')->string;

# サブコマンド「aaa」 - 引数(arg)の定義
my $fuga = $aaa->arg('fuga', 'fuga desu')->string;

# フラグ・引数を解析
my $cmd = $kingpin->parse;

if ($cmd eq "aaa") {
    # サブコマンド「aaa」のとき
    printf "subcommand: aaa\n";
    printf "flag: %s\n", $piyo->value;
    printf "arg : %s\n", $fuga->value;
}

下記のように実行できます。

$ perl hoge.pl aaa --piyo ppp bbbb
subcommand: aaa
flag: ppp
arg : bbb

--helpの自動生成

フラグや引数の説明を表示するようにするのって処理やメンテも大変ですよね・・・

kingpinの場合は、フラグや引数のときに説明をかけるようになっているので
定義するだけで--helpができちゃうのです。

hoge.pl
use strict;
use warnings;
use utf8;

use Getopt::Kingpin;

my $kingpin = Getopt::Kingpin->new;

# フラグ(flag)の定義
my $piyo = $kingpin->flag('piyo', 'piyo desu')->string;

# 引数(arg)の定義
my $fuga = $kingpin->arg('fuga', 'fuga desu')->string;

# フラグ・引数を解析
my $cmd = $kingpin->parse;

# 値を取得
printf "flag: %s\n", $piyo->value;
printf "arg : %s\n", $fuga->value;

--helpを実行してみると・・・

$ hoge.pl --help
usage: hoge.pl [<flags>] <fuga>

Flags:
  --help       Show context-sensitive help.
  --piyo=PIYO  piyo desu

Args:
  [<fuga>]  fuga desu

ね、簡単でしょ?

ショートフラグ(-h)でも使用したいという方は、

下記の処理を追加すればいけます。

$kingpin->flags->get("help")->short('h');

まとめ

引数処理するときは、Getopt::Kingpinを使って楽に処理しましょう!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1