目的
コマンドライン引数の解析を行う方法を一般化するイディオムの掲示を目的とします。
Ruby にはいくつかの引数解析用ライブラリが存在します。いずれにも一長一短ありますが、一連のツールを作る際には一貫性が必要です。
本イディオムは一貫性を確保するため僕が使っているものですので、あくまで一例ということになります。
基本形
僕は多くある引数解析ライブラリの中から、標準添付ライブラリにある otparse を利用しています。
理由は、
- 自由度が高い。
- ヘルプメッセージを出力してくれる。
- 標準添付ライブラリで実現できる。
の3点です。
以下、事例です。
# coding: UTF-8 require 'optparse' # デフォルト値を設定する config = { :arg3 => 'value3', # ... 続く } # 必須オプションを設定する required = [:arg1, :arg2] # 引数を解析する OptionParser.new do |opts| begin # オプション情報を設定する opts = OptionParser.new opts.on('-a ARG1', '--arg1 ARG1', "[必須]XXXを指定する。") { |v| config[:arg1] = v } opts.on('-b ARG2', '--arg2 ARG2', "[必須]YYYを指定する。") { |v| config[:arg2] = v } opts.on('-c ARG3', '--arg3 ARG3', "[任意]ZZZを指定する(デフォルト値:#{config[:arg3]})") { |v| config[:arg3] = v } # ... 続く opts.parse!(ARGV) # 必須オプションをチェックする for field in required raise ArgumentError.new("必須オプション(#{field})が不足しています。") if config[field].nil? end rescue => e puts opts.help puts puts e.message exit 1 end end # config の値を使って処理を行う # ... 続く
概要
本イディオムは以下をサポートします。
- 引数のデフォルト値を設定できる。
- 必須オプションのチェックができる。
- 必須オプションが足りなかったり、何らかのエラーがあればヘルプメッセージを出力してくれる。
解析したコマンドライン引数の値は config 変数に入れて、グローバルなものとして使います。
処理の可変部分は、大きく以下の3箇所です。
- デフォルト値を設定する。
- 必須オプションを設定する。
- オプションを設定する(設定方法については optparse を参照してください)。
該当箇所は説明しなくてもわかるでしょう。
標準で --help オプションによる説明文の表示のサポートします。以下、事例です。
>ruby example.rb --help Usage: test [options] -a, --arg1 ARG1 [必須]XXXを指定する。 -b, --arg2 ARG2 [必須]YYYを指定する。 -c, --arg3 ARG3 [任意]ZZZを指定する(デフォルト値:value3)
事例では全てのオプションの文字列としていますが、整数などとしても構いません。その場合は、
- デフォルト値の設定で 10 や 20 などの整数値を利用する。
- オプションの設定時は v.to_i を利用する。
とします。
文字列が整数を見なせなくても to_i は例外を出さず、解析できるところまでで数値を出します。検証の代わりにはならないことに注意してください。
カスタムバリデーションをどこでするか?
この事例では必須以上の検証を行なっていません。
もしも、カスタムバリデーションをするとしたらどこにするかですが、
- オプション情報を設定する箇所で実施する。
- 引数の解析を終えてからする。
- しない。
の3種類の選択肢があります。
僕の場合、あくまでツールという位置付ければあれば3を選択することがほとんどです。
メッセージについて
メッセージの書き方もなるべく揃えるという意味で、本ページを毎回参照するようにしています。そのために作ったページです。
また、Ruby 1.9.3-pXXX(正確には不明)から UTF-8 で文字列を出力しても、 利用している文字コードを認識してコマンドラインに文字列が化けること無く表示されるようになりました。
Ruby 2.0 系でも同様の恩恵が受けられます。
コメント
本ページの内容に関して何かコメントがある方は、以下に記入してください。
コメントはありません。 コメント/idiom/parse_command_args