3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PerlAdvent Calendar 2021

Day 8

Getopt::Longのスペルが覚えられない俺はとうとう覚える努力を放棄してラッパーを作った

Last updated at Posted at 2021-12-07

Getopt::Long − この便利だが悩ましいモジュール

Getopt::Longという便利なモジュールがある。

コマンドラインにおけるperl myscript.pl --input input.txt --output output.txtみたいなパラメータの処理を宜しくやってくれるモジュールである。こいつを組み込んだだけで、なにか自作スクリプトのグレードが2段階ぐらい上がったような錯覚を覚える。俺はそういう錯覚が大好きである。したがって俺はこのモジュールの機能のことはとても気に入っている。

しかしその反面、俺はこのモジュールに非常に大きな不満を抱いている。
それは、大文字と小文字がごちゃごちゃ混在していることと、単数形と複数形がごちゃごちゃ混在していることだ。

getoption.png

もうね、スクリプトを組むたびに、あれ、getopt::Longだっけ? Getopts::Longだっけ? getOpt::Longだっけ? と悩むわけですよ。

その状況を10年以上も続けて、どうやら俺は大文字と小文字の使い分けが超絶苦手であるとの事実を受け入れざるを得まいと悟ったわけだ1
正しいスペルが覚えきれないし、さらにいえば俺はシフトキーと言うやつが大嫌いだ。getOpぐらいのところで指がつりそうになる。

もう全部小文字にしてくれ。あと単数形一択に変えてくれ。…と本家に頼み込んでも受け入れてはくれまいから、自分用のwrapperを作って解決することにした。

名付けてarg.pm

以下に示すコードをarg.pmとして適切なディレクトリ2に放り込むと、スクリプト中でuse arg;できるようになる。
そう。use Getopt::Long;という長ったらしいコードを打つ代わりに、use arg;で事足りるのである。素晴らしい!
さらに、GetOptions(...の代わりにargv(...またはarg(...である。大文字フリー! シンプル! 快適!

use strict;
use warnings;
use Getopt::Long;
use Data::Dumper;

sub argv{
  my(%x)=@_;
  my %opt; my @dl;
  foreach my $key (sort keys %x){
    my($key1, $desc) = $key=~/(\S+)?(?:\s*(.*))?/;
    my($k,$k2,$t)    = $key1=~/(([^=]+)(?:=(\S+))?)/;
    $opt{$key1}         = $x{$key};
    ($t) or       $t = "s";
    my $t2 = ($t eq 's')?'string'
            :($t eq 'i')?'integer'
            :($t eq 'f')?'floating point value':'';
    push(@dl, "--$k2:\ttype=$t2. $desc");
  }
  (defined $dl[0]) and (not defined $opt{help}) and $opt{help}=sub {print join("\n", @dl), "\n"; exit()};
  GetOptions(%opt);
}
*arg = *argv;
1;

使い方は簡単

Getoptions()のラッパーなので、基本的にこの関数の使い方に準拠する形でarg()を使うことになる。

arg(
  "input=s"  => \$input,
  "output=s" => \$output
);

簡易ヘルプ機能も追加

ここまでで済ませても良かったのだが、なにかプログラムを作ると機能拡張しないと気が済まない性格でして。コマンドラインオプションの使い方を簡易にユーザに知らしめる「ヘルプ機能」をつけてしまった。具体的には次のように使う。

arg(
  "input=s Input file name" => \$input,
  "output=s Output file name" => \$output
);

このように、Getopt::Long互換なパラメータ文字列の後ろに、スペースを挟んで当該オプションの説明を書くのだ。すると、arg()内の細工により、--helpオプションが自動的に追加される(ただし、すでに明示的にhelpオプションが設定されている場合、この処理は抑止される)。

こんな感じで使える。

perl ~/work/testarg.pl --help
--input:	type=string. Input file name
--output:	type=string. Output file name

perldocを使うのが正道であるが、あれはちょっと大げさだからね。コマンドラインオプションの説明が一切示されないのも困るが、かといっていちいちperldocの独特の文法と格闘したくもない、という状況は少なくないと思う。そういうときにこの機能は便利であろうと考えている。

  1. だから俺はキャメルケースだのパスカルケースだのといった邪悪な命名法は絶対使わない。

  2. perl -le 'print for @INC'すると表示されるディレクトリのいずれかである。

3
0
2

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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?