rhanda | 元銀行員Web系エンジニアの日記

実務未経験からWeb系受託開発企業に転職したひよっこエンジニアが覚えたことや日々の感情を残すブログ

Rubyプログラム実行時に、コマンドライン引数を取得できるようオプションを作成

先日カレンダープログラムの作成に取り組みました。 その中でオプション設定や、それに係るエラーメッセージの表示を初めて行ったので、メモとして残すものです。



最終的に作ったコード

require 'optparse'

option = {}

OptionParser.new do |opt|
  begin
    opt.banner = "Usage: calender [options]"
    opt.on('-y year') {|v| option[:year] = v}
    opt.on('-m month') {|v| option[:month] = v}

    opt.parse!(ARGV)
  rescue OptionParser::InvalidOption => e
    puts "calender.rb:\s#{e.reason=('illegal option')}\s#{e.args.join(' ')}"
    puts opt.help
    exit
  rescue OptionParser::MissingArgument => e
    puts "option requires an argument\s#{e.args.join(' ')}"
    puts opt.help
    exit
  end
end

ひとつひとつ振り返る

rescue等の例外補足は置いておいて、オプションを使うためのコードはこの辺り

require 'optparse'

option = {}

OptionParser.new do |opt|
  opt.banner = "Usage: calender [options]"
  opt.on('-y year') {|v| option[:year] = v}
  opt.on('-m month') {|v| option[:month] = v}

  opt.parse!(ARGV)
end

例えば以下のようにすれば出力することで、コマンドライン引数を取得できていることがわかります。

p option[:year]
p option[:month]

% ruby test.rb -y 2021 -m 9

"2021"
"9"

オプションを作成

  opt.on('-y year') {|v| option[:year] = v}
  opt.on('-m month') {|v| option[:month] = v}

ここで-y-mのオプションを取り扱えるようにしています。(onメソッドリファレンス
今回はカレンダーのプログラムで年と月を扱いたかったので、最初にハッシュを作っておいて、それぞれyearmonthのキーの値にするようにしました。


また、このonメソッドの箇所では引数に関する設定が可能。

  • 引数を取らない場合
# コマンドラインにオプションを入力した場合は、 true を引数としてブロックを評価する。
on("-x"){|boolean| ...}
  • 引数を取る場合(本件の書き方)
# 'year'の部分は任意の文字列
on("-x year"){|val| ...}
  • 引数が必須ではない場合(上の書き方は必須)
# [ ] をつける
on("-x [year]"){|val| ...}


その他

opt.parse!(ARGV)

opt.parse!(ARGV)

Optionparser#parseは与えられたargvからオプションを取り除いたものを返す。
parseメソッドリファレンス

試してみたところ、これを書いていないと引数だけでなくオプション自体も要素として入っておりました。
今回は、オプション指定時に引数を入力し忘れた場合に例外を補足したい(OptionParser::MissingArgument)と考えており、オプションが入ってしまうと例補足することができなかったので、記述しました。

# 引数を入力し忘れた時
# parse!した場合
% ruby 02.calendar/calender.rb -y 

irb(main):001:0> ARGV
=> [] 


# parse!しなかった場合
% ruby 02.calendar/calender.rb -y 

irb(main):001:0> ARGV
=> ["-y"]


opt.banner = str

opt.banner = "Usage: calender [options]"

banner=メソッドは、--helpオプションを指定した時に表示されるサマリの最初に表示する文字列を指定することができます。 今回は例外補足時にUsage: calender [options]と表示したかったのでここで記述して、rescue節のputs opt.helpで出力するようにしておりました。


感想

カレンダー全体のプログラムについても、振り返ってまとめてみたい。