Elixirスクリプトを書く際に引数を受け付けたい場合があります。OptionParserを知っていると気軽に引数の解析ができて便利です。
Elixirスクリプトについては先日別の記事にまとめました。
System.argv/0で引数を取得
Elixirスクリプトの中でSystem.argv/0を実行すると渡された引数のリストを取得できます。
Elixirスクリプトでない環境で実行すると引数がないのでいつも空リストが帰ってきます。
iex
iex> System.argv()
[]
試しに渡された引数をプリントするだけのElixirスクリプトを書いてみます。
❯ cat <<-EOF > ./toukon.exs
System.argv()
|> Enum.each(&IO.puts/1)
EOF
❯ elixir toukon.exs --foo --bar=1
--foo
--bar=1
Elixirスクリプトの中で実行すると引数が空白で分割されたリストで帰ってきます。
OptionParser.parse!/2で引数を解析
OptionParser.parse!/2は引数のリストを解析し、あらかじめ宣言された名前と型に基づいて値を取り出します。設定を緩くすることもできますが、公式ドキュメントによると:strict
モードが推奨されています。特に理由がなければ:strict
モードを使うのが賢明です。
現時点で5つの方がサポートされています。
boolean型
iex> parse_boolean_option = &OptionParser.parse!(&1, strict: [hello: :boolean])
iex> parse_boolean_option.([])
{[], []}
iex> parse_boolean_option.(["--hello"])
{[hello: true], []}
iex> parse_boolean_option.(["--no-hello"])
{[hello: false], []}
iex> parse_boolean_option.(["--hello=true"])
{[hello: true], []}
iex> parse_boolean_option.(["--hello=false"])
{[hello: false], []}
iex> parse_boolean_option.(["--hello=0"])
** (OptionParser.ParseError) 1 error found!
--hello : Expected type boolean, got "0"
(elixir 1.14.0) lib/option_parser.ex:275: OptionParser.parse!/2
iex:13: (file)
count型
iex> parse_count_option = &OptionParser.parse!(&1, strict: [hello: :count])
iex> parse_count_option.(["--hello"])
{[hello: 1], []}
iex> parse_count_option.(["--hello", "--hello", "--hello"])
{[hello: 3], []}
string型
iex> parse_string_option = &OptionParser.parse!(&1, strict: [hello: :string])
iex> parse_string_option.(["--hello", "foo"])
{[hello: "foo"], []}
iex> parse_string_option.(["--hello=foo"])
{[hello: "foo"], []}
iex> parse_string_option.(["--hello"])
** (OptionParser.ParseError) 1 error found!
--hello : Missing argument of type string
(elixir 1.14.0) lib/option_parser.ex:275: OptionParser.parse!/2
iex:23: (file)
integer型
iex> parse_integer_option = &OptionParser.parse!(&1, strict: [hello: :integer])
iex> parse_integer_option.(["--hello", "0"])
{[hello: 0], []}
iex> parse_integer_option.(["--hello=0"])
{[hello: 0], []}
float
integer型と同様。
検証用Elixirスクリプト
引数を受け取り、解析し、結果をプリントするElixirスクリプトを書いてみます。
❯ cat <<-EOF > ./toukon.exs
System.argv()
|> OptionParser.parse!(
strict: [
aisatsu: :string,
year: :integer,
debug: :boolean
]
)
|> IO.inspect()
EOF
❯ elixir toukon.exs --aisatsu 元気ですかーーーーッ! --year=4 --debug
{[aisatsu: "元気ですかーーーーッ!", year: 4, debug: true], []}
ご参考までに