オプション -a, -b を受け付けるコマンドを作成する。
require 'optparse' opt = OptionParser.new opt.on('-a') {|v| p v } opt.on('-b') {|v| p v } opt.parse!(ARGV) p ARGV ruby sample.rb -a foo bar -b baz # => true true ["foo", "bar", "baz"]
オプションの指定はコマンドの直後である必要はない(上の例で、-b はオプションと して認識されている)。ただし、環境変数 POSIXLY_CORRECT が定義してあると この挙動は変更される。
env POSIXLY_CORRECT=1 ruby ./sample.rb -a foo bar -b baz # => true # -a はオプションと解釈 ["foo", "bar", "-b", "baz"] # -b は非オプションと解釈
parse!() により、コマンドライン(ARGV)の解析を行う。 parse!() では、ARGV からオプションが取り除かれる。 これを避けるには parse() を使う。
require 'optparse' opt = OptionParser.new opt.on('-a') {|v| p v } opt.on('-b') {|v| p v } # parse() の場合、ARGVは変更されない。 # オプションを取り除いた結果は argv に設定される。 argv = opt.parse(ARGV) p argv
定義していないオプションを指定すると例外 OptionParser::InvalidOption が 発生する。(このようなときに usage を出力するには?)
ruby ./sample.rb -c /usr/local/lib/ruby/1.9/optparse.rb:1428:in `complete': invalid option: -c (OptionParser::InvalidOption) from /usr/local/lib/ruby/1.9/optparse.rb:1426:in `catch' from /usr/local/lib/ruby/1.9/optparse.rb:1426:in `complete' from /usr/local/lib/ruby/1.9/optparse.rb:1287:in `order!' from /usr/local/lib/ruby/1.9/optparse.rb:1256:in `catch' from /usr/local/lib/ruby/1.9/optparse.rb:1256:in `order!' from /usr/local/lib/ruby/1.9/optparse.rb:1336:in `permute!' from /usr/local/lib/ruby/1.9/optparse.rb:1363:in `parse!' from /usr/local/lib/ruby/1.9/optparse.rb:1356:in `parse' from ./sample.rb:9
OptionParser 自体は、どのオプションが指定されたかを記憶しない。 後の処理の方で、オプションによる条件判断を加えるには、 他のコンテナに格納する(しかない?)。
require 'optparse' opt = OptionParser.new OPTS = {} opt.on('-a') {|v| OPTS[:a] = v } opt.on('-b') {|v| OPTS[:b] = v } opt.parse!(ARGV) p ARGV p OPTS ruby sample.rb -a foo bar -b baz # => ["foo", "bar", "baz"] {:a=>true, :b=>true}
OprionParser.new はブロックを受け付ける。ブロックの引数は生成した インスタンスなので、以下の書き方ができる。
require 'optparse' OptionParser.new {|opt| opt.on('-a') {|v| p v } opt.on('-b') {|v| p v } opt.parse!(ARGV) } p ARGV
この書き方の利点は、
ぐらいか?
optparse.rb を require すると、ARGV に OptionParser::Arguable の機能 が加わる。このことにより、以下の書き方ができるようになる。
require 'optparse' ARGV.options {|opt| opt.on('-a') {|v| p v } opt.on('-b') {|v| p v } opt.parse! } p ARGV ruby sample.rb -a foo bar -b baz # => true true ["foo", "bar", "baz"]
といった違いがある(そのぐらいの違いしかない?)。
特に利点があるわけではない(と思う)が、optparse 添付のサンプルはこの書 き方になっている。
on() メソッドのオプション定義で末尾に何かを書くと、そのオプション は引数を受け付けることの指定となる。
require 'optparse' opt = OptionParser.new opt.on('-a VAL') {|v| p v } # <- " VAL" を追加 opt.on('-b') {|v| p v } opt.parse!(ARGV) p ARGV ruby sample.rb -a foo bar -b baz # => "foo" true ["bar", "baz"]
オプションの末尾の書き方の基準は、「ヘルプ の見栄えが良くなるように書く」である。
オプションの引数を省略すると例外 OptionParser::MissingArgument が発生する。
ruby ./sample.rb -a /usr/local/lib/ruby/1.9/optparse.rb:455:in `parse': missing argument: -a (OptionParser::MissingArgument) from /usr/local/lib/ruby/1.9/optparse.rb:1295:in `order!' from /usr/local/lib/ruby/1.9/optparse.rb:1256:in `catch' from /usr/local/lib/ruby/1.9/optparse.rb:1256:in `order!' from /usr/local/lib/ruby/1.9/optparse.rb:1336:in `permute!' from /usr/local/lib/ruby/1.9/optparse.rb:1363:in `parse!' from ./sample.rb:7
オプションの引数が必須でないことを示すには、" ["(空白+[) を付ける
require 'optparse' opt = OptionParser.new opt.on('-a [VAL]') {|v| p v } # <- [VAL] を追加 opt.on('-b') {|v| p v } opt.parse!(ARGV) p ARGV ruby sample.rb -a # => nil []
同様に、ヘルプの見栄えが良いように "VAL]" を付加している。
ロングオプションは、on() の引数に '--'で始まるオプションを指定する。
require 'optparse' opt = OptionParser.new opt.on('-a', '--foo') {|v| p v } opt.on('--bar') {|v| p v } opt.parse!(ARGV) p ARGV ruby sample.rb -a foo bar --bar baz # => true true ["foo", "bar", "baz"]
--[no-]...などとすることで、否定型のオプションを指定することができる。
require 'optparse' opt = OptionParser.new opt.on('-a', '--foo') {|v| p v } opt.on('--[no-]bar') {|v| p v } opt.parse!(ARGV) p ARGV ruby sample.rb -a foo bar --bar baz --no-bar # => true true false # <- --no-bar の指定による。 ["foo", "bar", "baz"]
オプションに対する引数も指定できる。ショートオプションと同じだが、 GNUの慣習にあわせて
opt.on('-a', '--foo=VAL') {|v| p v } opt.on('--[no-]bar[=VAL]') {|v| p v }
と "=" を使うのが良いと思われる。
オプションを指定する時は、どのオプションか一意に決まる長さまで指定す れば良い。
require 'optparse' opt = OptionParser.new opt.on('-a', '--foo') {|v| p v } opt.on('--[no-]bar') {|v| p v } opt.parse!(ARGV) p ARGV ruby sample.rb --fo
この例では、--fo は、--foo を指定したのと同じになる。この例なら --f まで省略できる。(あまり例がよくない)
デフォルトで、--help と --version オプションを認識する。
ruby ./sample.rb --help # => Usage: sample [options] ruby ./sample.rb --version # => *出力なし*
--version は、トップレベルに Version 定数が定義されていると出力される。 (優先度は低いが VERSION 定数も参照する。Ruby のバージョンを示す VERSION 定数が ruby 1.8 までは定義されているので注意)
require 'optparse' opt = OptionParser.new Version = "1.2.3" # opt.version = "1.2.3" opt.parse!(ARGV) ruby ./sample.rb --version # => sample 1.2.3
on の引数にそのオプションの説明を加えると --help の出力に反映される。
require 'optparse' opt = OptionParser.new opt.on('-a', 'description of -a') {|v| p v } opt.on('-b', 'description of -b') {|v| p v } opt.parse!(ARGV) p ARGV ruby ./sample.rb --help # => Usage: sample [options]
が、これだけだとダメらしい。
opt.on('--help', 'show this message') { puts opt; exit }
をオプション定義に追加するか、ARGVを使った書き方 にする(以下)。
require 'optparse' ARGV.options {|opt| opt.on('-a', 'description of -a') {|v| p v } opt.on('-b', 'description of -b') {|v| p v } opt.parse! } p ARGV ruby ./sample.rb --help # => Usage: sample [options] -a description of -a -b description of -b