OptionParser の省略可引数は Placed 推奨

ruby 添付ライブラリ optparse は、 オプションの省略可引数を Optional と Placed の 2 種類に分けて区別します。 特に理由がなければ、 Optional を使わず、 Placed を使いましょう。 この 2 つには、 コマンドライン解釈時に、 オプションと省略可引数の間の区切りに空白を許すかどうかの違いがあります。 Optional は区切りに空白を使えません。 一文字オプションでは引数を直後にタイプし、 長オプションでは等号で区切って引数をタイプしなければなりません。 Placed は、 Optional に加えて、 Required と同じく区切りに空白を使うことができるようになります。

なお、 この区別は ruby-1.8 添付時から既に存在しており (Switch.guess)、 ドキュメントではずっと曖昧なままになっています。

            Optional        Placed          Required
-a          省略 (nil)      省略 (nil)      エラー
-aA         "A"             "A"             "A"
-a A        省略 (nil)      "A"             "A"
--opt       省略 (nil)      省略 (nil)      エラー
--opt=A     "A"             "A"             "A"
--opt A     省略 (nil)      "A"             "A"

Optional か Placed かは、 on メソッドで省略可引数を指定する記法で区別します。 オプションと省略可引数の間に一つ以上の空白があると Placed になり、 空白がないか等号で区切ると Optional になります。 一方、 Required は等号と空白の区切りで解釈を変えません。

#@<exam.rb@>=
require 'optparse'

opt = OptionParser.new
opt.banner = "usage: ruby #{$0} [option]"
opt.version = '0.0.1'
opt.on('-a', '--opa[OPTIONAL]', 'guess Switch::OptionalArgument')
opt.on('-b', '--opb=[OPTIONAL]', 'guess Switch::OptionalArgument')
opt.on('-c', '--opc [PLACED]', 'guess Switch::PlacedArgument')
opt.on('-d', '--opd=REQUIRED', 'guess Switch::RequiredArgument')
opt.on('-e', '--ope REQUIRED', 'guess Switch::RequiredArgument')
opt.parse!(ARGV)
p ARGV

このような記法の違いがあるので、 オンライン・ドキュメントにある次の書き方をすると Optional になり、 空白で区切れなくなることを頭に置いておいた方が良いでしょう。 optparse を使う gem の多くは Placed になっているので、 Optional にすると空白区切りできなくなって利用者が困惑すると思われます。

https://docs.ruby-lang.org/ja/2.5.0/library/optparse.html#longoption

オプションに対する引数も指定できます。ショートオプションと同じだが、 GNUの慣習にあわせて

opt.on('-a', '--foo=VAL') {|v| p v }
opt.on('--[no-]bar[=VAL]') {|v| p v }

"=" を使うのが良いと思われます。

さて、 上のスクリプト exam.rb では、 -a と -b を Optional、 -c を Placed、 -d と -e を Required としてコマンドラインを処理します。

$ ruby exam.rb f g
["f", "g"]

Optional では、 空白を引数との区切り記号に使えません。 一文字オプションでは直後に続けて、 長オプションでは等号で区切って引数を指定します。 引数のつもりで空白で区切っても、 引数と解釈されずに ARGV に残ります。

$ ruby exam.rb -a --opa -aA1 --opa=A2 -a A3 --opa A4 f g
-a nil
-a nil
-a "A1"
-a "A2"
-a nil
-a nil
["A3", "A4", "f", "g"]
$ ruby exam.rb -b --opb -bB1 --opb=B2 -b B3 --opb B4 f g
-b nil
-b nil
-b "B1"
-b "B2"
-b nil
-b nil
["B3", "B4", "f", "g"]

Placed は、 Optional の書き方に加えて、 空白で区切って引数をタイプすることも可能です。

$ ruby exam.rb -c --opc -cC1 --opc=C2 -c C3 --opc C4 f g
-c nil
-c nil
-c "C1"
-c "C2"
-c "C3"
-c "C4"
["f", "g"]

Required も Placed 同様です。 一文字オプションでは直後に引数をタイプしても良いですし、 空白で区切ってもかまいません。 長オプションでは等号でも空白でも区切ることができます。

$ ruby exam.rb -dD1 --opd=D2 -d D3 --opd D4 f g
-d "D1"
-d "D2"
-d "D3"
-d "D4"
["f", "g"]
$ ruby exam.rb -eE1 --ope=E2 -e E3 --ope E4 f g
-e "E1"
-e "E2"
-e "E3"
-e "E4"
["f", "g"]