Rubyのoptparseの挙動について
もう知ってる人にとっては、当たり前じゃん何言ってるのみたいな内容かもしれませんが、私は最近知ったので。。
Rubyには optparse
というコマンドライン引数を読み取るライブラリが標準でついてくる。
これを使ってよくバッチ処理とかに使うスクリプトを書いてたりする。
この前書いたコードで以下のようなオプションを書いた。
OPTIONS = {} OptionParser.new do |opt| opt.on('-n', '--no-daemon') {|v| OPTIONS[:no_daemon] = v} opt.parse!(ARGV) end
デーモン状態で動くほうが通常モードだったアプリケーションなので、デーモン状態でない時を明示的にしたいときにと思い、 --no-daemon
とした。
当初はこの引数を以下のように使用していた。
unless OPTIONS[:no_daemon] # :no_daemonがfalseだったときの処理(デーモン状態で動かしたいときの処理) end
しかしどうも期待どおりの挙動を示してくれない(常にデーモン状態になる)のでドキュメントを見た。library optparse
--[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"]
noってつけると否定形になって、falseが返ってくるのか
いつもTrueの感覚で書いていたので普通にミスった。
つわけで当初書いたここのコードブロックは
--no-daemonオプションあり => false --no-daemonオプションなし => nil => false
となるので、常にデーモン状態となったわけだった。
最終的に以下のように修正した。
if OPTIONS[:no_daemon].nil? # :no_daemonがfalseだったときの処理(デーモン状態で動かしたいときの処理) end
こっちのほうが素直な実装だとは思う。