Ruby: コマンドライン引数の解析で使うoptparseをもっと柔軟に
オプションの無い引数を扱いたい
Rubyでコマンドライン引数を解析するときは、optparse (OptionParser) を使うと便利です。
しかし、OptionParser#parse! は、"-a", "--long-option"みたいなオプションを使わない引数を扱う場合に不便です。
つまり、コマンドラインで
$ ruby foo.rb -o file_output.txt file_input.html
みたいなことをしようと思うと、RubyでOptionParserを使う前に
# ruby opt = OptionParser.new @option[:file] = ARGV.pop # ... opt.on('-o FILE','--output FILE','Output Filename') {|v| @option[:file_output] = v } # ... opt.parse!(ARGV)
みたいに、ARGV.popで引数を取り出す必要があります。
この場合、オプションの無い引数が必ず末尾に来ないといけないので、
かなり窮屈なコマンドインタフェースになります。
オプション無しの引数をもっと柔軟に扱う
それを解決する方法は、OptionParser#parse! を使うのではなく、OptionParser#permute! を使うことです。
instance method OptionParser#permute!
permute!(argv = self.default_argv) -> [String]
与えられた argv を破壊的にパースします。argv からオプションがすべて取り除かれます オプションではないコマンドの引数(下の例で言うと somefile)があってもパースを中断しません。 argv を返します。下の例で言うと、order と違いコマンドの引数 somefile よりも後ろにオプションを置くことが できます。
例:
$ cat opt.rb
require 'optparse'
opt = OptionParser.newopt.on('-a [VAL]') {|v| p :a }
opt.on('-b ') {|v| p :b }opt.permute!(ARGV)
p ARGV$ ruby opt2.rb -a foo somefile -b
:a
:b
["somefile"]
これを使うと、パース(permute)後のARGVにオプション無し引数が残ってくれるので、
ARGV.popでオプション無し引数を簡単に取り出せます。
(順番さえ守れば)オプション無し引数の位置も好きな位置に置けます。
例えば、以下のように、オプション付き引数(-o file_output.txt)の前に
オプション無しの引数(file_input.html)を与えることもできます。
$ ruby foo.rb file_input.html -o file_output.txt