Elixir OptionParser接受[“ - form”,“blah”]

时间:2017-05-03 09:45:07

标签: elixir

我是学习Elixir的新手。

作为一个起点,我想实现小型命令行应用程序。我在iex中偶然发现了以下内容:

args = ["--form", "blah"]
OptionParser.parse(args, switches: [src: :string])

我希望得到{[],[],[form: "blah"]}的结果。

相反,我会收到{[form: "blah"],[],[]}

我忽略了什么吗?

另外:

如果我分配args args=["--folm", "lolo"],结果是{[], [], [{"--folm", "lolo"}]}我期望的结果。

我认为switches:定义有效开关。而且,由于我没有定义form: :string,我不希望它被接受。 form似乎有些特别之处,我现在还没有。

1 个答案:

答案 0 :(得分:2)

  

我认为switches:定义有效开关。而且,由于我没有定义form: :string,我不希望它被接受。 form似乎有些特别之处,我现在还没有。

在"动态"模式,在当前Erlang VM中以原子形式存在的名称的开关被解析为有效列表,而不存在的那些开关被放入错误列表中。这可以这样验证:

iex(1)> OptionParser.parse(["--form", "blah"], switches: [src: :string])
{[form: "blah"], [], []}
iex(2)> OptionParser.parse(["--folm", "blah"], switches: [src: :string])
{[], [], [{"--folm", "blah"}]}
iex(3)> :folm # Create this atom
:folm
iex(4)> OptionParser.parse(["--folm", "blah"], switches: [src: :string])
{[folm: "blah"], [], []}

--form在第一次尝试时解析,因为Elixir在启动时在某处创建了该原子:

$ erl -noshell -eval 'io:format("~p", [binary_to_existing_atom(<<"form">>, utf8)]), init:stop().'
form

这将在&#34;解析动态开关&#34; OptionParser.parse/2

  

换句话说,当使用动态模式时,Elixir将执行正确的操作并仅解析运行时使用的选项,而忽略所有其他选项。如果要解析所有开关,无论它们是否存在,都可以通过传递allow_nonexistent_atoms:true作为选项来强制创建原子。当您构建接收动态命名参数的命令行应用程序但在长时间运行的系统上必须小心使用时,此选项很有用。

使用严格切换模式可以关闭此行为:

iex(5)> OptionParser.parse(["--form", "blah"], strict: [src: :string])
{[], ["blah"], [{"--form", nil}]}
iex(6)> OptionParser.parse(["--folm", "blah"], strict: [src: :string])
{[], ["blah"], [{"--folm", nil}]}
iex(7)> OptionParser.parse(["--form", "blah", "--src", "blah2"], strict: [src: :string])
{[src: "blah2"], ["blah"], [{"--form", nil}]}