ropt

roptは、Ruby用の簡単で実用的なコマンドラインオプション解析ライブラリです。 GNU getopt に似た文法でオプションの仕様を定義できます。

特徴

動作条件

インストール方法

ファイルは lib/ropt.rb だけですが、一応インストーラが付いています。 以下のコマンドでインストールされます。

% ruby install.rb config
% ruby install.rb setup
% ruby install.rb install

使い方

シンプルな例

添付のスクリプト example.rb を例に取ります。このスクリプトは以下のコマンドラインオプションを受け付けます。

def usage
  STDERR.puts("\
Usage: #{File.basename($0)} [OPTION]... ARG1 ARG2
Options
  -a                  短いオプション/引数無し
  -b ARG              短いオプション/引数あり
  -c ARG              短いオプション/引数あり&複数回指定可能
  --long-a            長いオプション/引数無し
  --long-b ARG        長いオプション/引数あり
  --long-c ARG        長いオプション/引数あり&複数回指定可能
")
  exit 1
end

まず、 ROpt.parse で引数を解析し、結果を得ます。 失敗時にはnilが返ります。 その場合usageメソッドを呼び出し、文法を表示します。

require "ropt"
opt = ROpt.parse(ARGV, "ab:c::", "long-a", "long-b:", "long-c::") || usage

opt の [] メソッドでオプションの値を得られます。

puts("-a specified.") if opt[:a]
puts("-b is #{opt[:b].inspect}") if opt[:b]
puts("-c are #{opt[:c].inspect}") unless opt[:c].empty?

puts("--long-a specified.") if opt['long-a']
puts("--long-b is #{opt['long-b'].inspect}") if opt['long-b']
puts("--long-c are #{opt['long-c'].inspect}") unless opt['long-c'].empty?

また、 args メソッドで残りの引数を得られます。

puts("Rest arguments: #{opt.args.inspect}") unless opt.args.empty?

適当な引数を与えて実行してみましょう。

% ruby example.rb -ab B -c C1 -c C2 --long-a --long-b B --long-c C1 -- 1 2 3
-a specified.
-b is "B"
-c are ["C1", "C2"]
--long-a specified.
--long-b is "B"
--long-c are ["C1"]
Rest arguments: ["1", "2", "3"]

誤った引数を与えれば文法が表示されます。

% ruby example.rb --unknown
Usage: example.rb [OPTION]... ARG1 ARG2
Options
  -a                  Short option / Without argument
  -b ARG              Short option / With argument
  -c ARG              Short option / With argument, multiple options allowed.
  --long-a            Long option / Without argument
  --long-b ARG        Long option / With argument
  --long-c ARG        Long option / With argument, multiple options allowed.

動的な引数の処理

ROpt.parse にブロックを与えると、 仕様に定義されているもの以外のオプションが現れたときの処理を記述できます。

添付のスクリプト example2.rb がその例です。

require "ropt"
opt = ROpt.parse(ARGV, nil, "static") { |option, argv|
  if %r"^dynamic" =~ option
    puts("Dynamic option --#{option} with argument `#{argv.shift}'.")
    true
  else
    STDERR.puts("Unkown option: `#{option}'")
    exit 1
  end
}
puts("--static.") if opt[:static]

これは --dynamicXXX というオプションを、すべて引数付きオプションとして受け付けます。 それ以外はエラーを出力して終了します。

% ./example2.rb --static --dynamic1 arg
Dynamic option --dynamic1 with argument `arg'.
--static.

% ./example2.rb --unknown
Unkown option: `unknown'

ブロックの引数については、リファレンスの ROpt.parse を参照してください。

リファレンス

ROpt

ROpt.parse(argv, short_option_spec, *long_option_spec, ...)
ROpt.parse(argv, short_option_spec, *long_option_spec, ...) { |option, argv| ...}

コマンドライン引数の配列argvを解析し、 解析結果を格納したROpt::ParseResultオブジェクトを返します。 不明なオプションを含むなどの文法エラーを検出した場合には、 解析を中断してnilを返します。

short_option_specには短いオプションとして受け付ける文字を以 下のように一つ以上指定します。

long_option_specには長いオプションとして受け付ける文字列を、 以下のように列挙します。

どちらの場合も、引数があっても無くてもよいオプションは定義できません。 また、getoptsのようにデフォルト値は指定できません。 不正な文字列をshort_option_spec, long_option_specに渡すと、 例外InvalidParseRuleErrorが発生します。

ブロックを渡すと、想定外のオプションが現れた場合の処理を記述できます。 ブロックの引数optionにはオプションの文字列が、 argvにはそのオプション以降の引数の配列が渡されます。

ブロックの中では、場合に応じて以下の処理を行って下さい。

ROpt::ParseResult

ROpt.parseによって返される、解析結果を格納したオブジェクトです。 オプションの有無や引数、オプションでは無い残りの引数を取得することができます。

ROpt::ParseResult#[option]

オプションoption(文字列もしくはSymbol)の状態を返します。 オプションの状態によって以下の値が返ってきます。

optionが仕様外のオプションだった場合には、例外IndexErrorが発生します。 これは、仕様を定義し忘れるミスを防ぐためです。

ちなみに、optionに整数を渡すと ROpt::ParseResult#args[option]と同じ意味になります。

ROpt::ParseResult#args

このオブジェクトが保持する、オプションでは無い残りの引数の配列を返します。

ROpt::ParseResult#options

このオブジェクトが保持する、オプションの状態を格納するハッシュを返します。 通常オプションの状態を得るには、 ROpt::ParseResult#[option]を使います。

利用条件と連絡先

Rubyと同じライセンスの下で、自由に利用できます。 要望やバグレポートは 白井 薫 <shirai@korinkan.co.jp> までお願いします。