Rubyのoptparse使い方まとめ

# はじめに
Rubyでコマンドライン引数を使う際は、`optparse`でオプションを指定することができます。
今回は`optparse`の使い方を簡単にまとめていきたいと思います。

# 用語について
まず各用語について確認します。

- オプション
  →コマンドの振る舞い方を指定する。
-(ハイフン)とアルファベット１文字で指定する。

- コマンドライン引数
  →プログラムを実行する際に指定する引数(文字列)のこと。


   

# 使い方
以下の手順でoptparseの設定を行います。
1. OptionParseオブジェクトを生成
1. オプションを登録
1. parseメソッドでコマンドラインを解析

具体的なソースコードは以下のようになります。
```ruby:sample.rb
require 'optparse'
opt = OptionParse.new

opt.on('-m'){|v| p v}

opt.parse!(ARGV)
p ARGV
```

```zsh:オプション+引数ありの実行結果
$ ruby sample.rb -m hoge
true
["hoge"]
```
```zsh:オプションありのみの実行結果
$ ruby sample.rb -m
true
[]
```
```zsh:オプションなしの実行結果
$ ruby sample.rb
[]
```


## 1. OptionParseオブジェクトを生成
`optparse`ライブラリを読み込み、`OptionParse`オブジェクトを生成します。

```ruby:sample.rb
# optparseライブラリを読み込む
require 'optparse'
# OptionParseオプジェクトを生成する 
opt = OptionParse.new
```

## 2. オプションを登録
`on`メソッドを使用することで、コマンドライン引数のオプションを登録することができます。
以下のコードでは、`-m`オプションを指定しています。
引数`v`には、オプションが指定されたことを示す`true`が入ります。

```ruby:sample.rb
# onメソッドを使用してオプションを登録
opt.on('-m'){|v| p v}
```


## 3. parseメソッドでコマンドラインを解析
`parse!`メソッドでコマンドラインを解析します。
`parse!`は破壊的メソッドであるため、`ARGV`の内容はオプションが取り除かれた形となります。

```ruby:sample.rb
# parse!メソッドでコマンドラインを解析
opt.parse!(ARGV)
# ARGVを出力する
p ARGV
```

# その他例
## ARGVからオプションを取り除かないようにする
ARGVからオプションを取り除かないようにするには、`parse`メソッドを用います。

```ruby:sample.rb
require 'optparse'
opt = OptionParser.new

opt.on('-m') {|v| p v }

# parseの場合、ARGVは変更されない
# argvにオプションを取り除いたものが設定される
argv = opt.parse(ARGV)

p ARGV
p argv
```

```zsh:オプション+引数ありの実行結果
$ ruby sample.rb -m hoge
true
["-m","hoge"]
["hoge"]
```
```zsh:オプションありのみの実行結果
$ ruby sample.rb -m
true
["-m"]
[]
```
```zsh:オプションなしの実行結果
$ ruby sample.rb
[]
[]
```

## オプションの指定情報を他のコンテナに代入する
オプションの指定情報を他のコンテナに代入することも可能です。
```ruby:sample.rb
require 'optparse'
opt = OptionParser.new

params = {}

# paramsの「mキー」にtrueを代入
opt.on('-m') {|v| params[:m] = v }

opt.parse!(ARGV)
p ARGV
p params

```
```zsh:オプション+引数ありの実行結果
$ ruby sample.rb -m hoge
["hoge"]
{:m=>true}
```
```zsh:オプションありのみの実行結果
$ ruby sample.rb -m
[]
{:m=>true}
```
```zsh:オプションなしの実行結果
$ ruby sample.rb 
[]
{}
```
parseメソッドに`:into`を指定することで、同様にオプションの指定情報を格納できます。
```ruby:sample
require 'optparse'
opt = OptionParser.new

params = {}

opt.on('-m') {|v| v }

# parseメソッドに":into"を指定する
opt.parse!(ARGV, into: params)
p ARGV
p params
```

## オプションの引数を指定する
オプションの引数を指定する場合は、`VAL`を追加します。
オプションの引数が指定されなかった場合は、`OptionParser::MissingArgument`エラーが発生します。

```ruby:sample.rb
require 'optparse'
opt = OptionParser.new

# "VAL"を追加
# "v"にオプションの引数が渡される
opt.on('-m VAL') {|v| p v }         

opt.parse!(ARGV)
p ARGV
```
```zsh:オプション+引数ありの実行結果
$ ruby sample.rb -m hoge
"hoge"
[]
```
```zsh:オプションありのみの実行結果
$ ruby sample.rb -m
missing argument: -m (OptionParser::MissingArgument)
```
```zsh:オプションなしの実行結果
$ ruby sample.rb
[]
```

オプションの引数が必須でない場合は、`[VAL]`を追加します。
```ruby:sample.rb
require 'optparse'
opt = OptionParser.new

# "[VAL]"を追加
opt.on('-m [VAL]') {|v| p v }         

opt.parse!(ARGV)
p ARGV
```
```zsh:オプションありのみの実行結果
$ ruby sample.rb -m
nil
[]
```


# 参考
- [library optparse (Ruby 3.2 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/library/optparse.html)
- [class OptionParser (Ruby 3.2 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/class/OptionParser.html)