# はじめに

OptionParser はコマンドライン引数のオプションの解析を簡単に行うためのクラスである。

コマンドライン引数の解析というのは、だいたいどんなツールでもほとんど同じパターンが必要になる。 そしてこれにはいくつかの流儀のようなものがある。

## 短形式と長形式オプション

Unix 上のツールのオプションスイッチは、伝統的に`-` に続く英字一文字で指定される。 これは通常複数のものを続けて指定することもできる。 例えば`ls`コマンドなら、次の２つは同じ動作をする。

    ls -l -a

    ls -la

また、最近の GNU tools などは `--` で始まる長い名前のスイッチも使える。

    ls --all

OptionParserはこの両方の形式をサポートする。 もちろん混ぜて使うことも可能。

# 使い方

## 一番単純な使い方

    require 'optparse'
    ARGV.options {|q|
      q.def_option('--help', 'show this message') {puts q; exit(0)}	# <- (1)
      q.parse!
    } or exit(1)

これだけで、`--help`、`--hELp`、`--hEl`、`--HE`、 `--h` などの長形式のスイッチ*1に加えて、`-h`という短形式のオプションスイッチが使えるようになる。 OptionParserでは、短形式のスイッチが見付からなかった場合、自動的に長形式の省略形とみなすためだ。

このスクリプトに対して`--help`スイッチを指定すると、(1)のブロックが実行される。 `puts q`というのは、指定できるオプションの一覧を表示することを意味する。

正しくないスイッチを指定されたときには、エラーメッセージを`STDERR` に表示して終了コード1で終了する。

*2

## フラグの設定

通常、オプションスイッチが指定された場合は何らかのフラグ*3などをセットしておいて、あとで参照できるようにする。

    require 'optparse'
    $verbose = false
    ARGV.options {|q|
      q.def_option('-v', '--verbose', 'run verbosely') {$verbose = true}
      q.parse!
    } or exit(1)
    puts "verbose=#$verbose"

これで、`--verbose`や`-V`などと指定されれば、(1)のブロックが実行されて $verboseには`true`がセットされることになる。

## フラグの on/off

フラグの指定を取り消すようにすることもできる。

    require 'optparse'
    $verbose = false
    ARGV.options {|q|
      q.def_option('-v', '--[no-]verbose', 'run verbosely') {|$verbose|}
      q.parse!
    } or exit(1)
    puts "verbose=#$verbose"

--verboseに[no-]というのが付いているが、これは否定形が使えることを意味している。 `--no-verbose`と指定されれば、$verboseには`false`がセットされる。

## 否定形のフラグ

    require 'optparse'
    $execute = true
    ARGV.options {|q|
      q.def_option('-v', '--[no-]verbose', 'run verbosely') {|$verbose|}
      q.def_option('-n', '--no-execute', 'not actually run') {|$execute|}
      q.parse!
    } or exit(1)
    puts "verbose=#$verbose"
    puts "execute=#$execute"

次の`--no-execute`では、[no-]の替わりにno-となっている。 この違いは、どちらがデフォルトになっているか、つまり短形式が肯定形か否定形かということだ。 []付きの場合は肯定形、付いていない場合は否定形がデフォルトになる。 つまり、単に`-v`と指定されたときは$verboseは`true`になるが、 `-n`なら$executeには`false`がセットされる。

*1 長形式のスイッチに対しては大文字小文字は区別しない
*2 `def_option`というのは古いバージョンでは使えない。 替わりに`on`を使う。
*3 グローバル変数が使われることも多い