选择分析器 | OptionParser
OptionParser
此模块包含解析命令行选项的函数。
摘要
类型
argv()errors()options()parsed()
函数
next(argv, opts \ [])
解析一个选项的低级函数
parse(argv, opts \ [])
解析argv
为关键字列表
parse!(argv, opts \ [])
一样parse/2
,但提出了一个OptionParser.ParseError
如果给出任何无效选项例外
parse_head(argv, opts \ [])
类似,parse/2
但只解析头部argv
; 只要发现一个非开关,它就会停止解析
parse_head!(argv, opts \ [])
一样parse_head/2
,但提出了一个OptionParser.ParseError
如果给出任何无效选项例外
split(string)
将字符串拆分成argv/0
块
to_argv(enum, opts \ [])
接收可枚举的键值并将其转换为 argv/0
类型
argv()
argv() :: [String.t]
errors()
errors() :: [{String.t, String.t | nil}]
options()
options() :: [switches: keyword, strict: keyword, aliases: keyword]
parsed()
parsed() :: keyword
功能
next(argv, opts \ [])
next(argv, options) ::
{:ok, key :: atom, value :: term, argv} |
{:invalid, String.t, String.t | nil, argv} |
{:undefined, String.t, String.t | nil, argv} |
{:error, argv}
解析一个选项的低级函数。
它接受与parse/2
和parse_head/2
因为这两个函数都构建在此函数之上。这一职能可返回:
{:ok, key, value, rest}
-选择key
带着value
成功解析
{:invalid, key, value, rest}
- 该选项key
无效value
(当根据交换机类型无法解析该值时返回)
{:undefined, key, value, rest}
- 该选项key
未定义(当开关未知时,以严格模式返回)
{:error, rest}
-在给定的argv
parse(argv, opts \ [])
parse(argv, options) :: {parsed, argv, errors}
解析argv
进入关键字列表。
它返回一个三元组元组的形式{parsed, args, invalid}
,其中:
parsed
是包含{switch_name, value}
元组的解析开关的关键字列表;switch_name
是表示开关名称的原子,而该开关value
的值是根据解析的opts
(参见“示例”一节获取更多信息)
args
中的剩余参数列表。argv
作为字符串
invalid
是无效的选项列表{option_name, value}
,其中option_name
是原始选项value
是nil
如果不期望的选项被或字符串值,如果值不具有相应的选项预期的类型
Elixir将开关转换为下划线原子,因此--source-path
变成了:source_path
。这样做是为了更好地适应Elixir公约。但是,这意味着交换机不能包含下划线,并且包含下划线的交换机总是返回到无效交换机列表中。
在解析时,常见的做法是列出开关及其预期类型:
iex> OptionParser.parse(["--debug"], switches: [debug: :boolean])
{[debug: true], [], []}
iex> OptionParser.parse(["--source", "lib"], switches: [source: :string])
{[source: "lib"], [], []}
iex> OptionParser.parse(["--source-path", "lib", "test/enum_test.exs", "--verbose"],
...> switches: [source_path: :string, verbose: :boolean])
{[source_path: "lib", verbose: true], ["test/enum_test.exs"], []}
下面我们将探讨选项解析器的有效开关和操作模式。
备选方案
支持下列选项:
:switches
或:strict
-见下文“切换定义”一节
:allow_nonexistent_atoms
-参见下面的“解析动态开关”一节
:aliases
-见下文“别名”一节
开关定义
开关可以通过以下两个选项中的一个指定:
:switches
-定义一些开关及其类型。此函数仍然试图解析不在此列表中的开关。
:strict
-定义严格的开关。任何进入argv
在无效选项列表中返回未指定的列表。
这两个选项都接受{name, type}
元组的关键字列表,其中name
的原子是定义开关名称type
的原子,并且是指定此开关值的类型的原子(有关可能的类型和类型的更多信息,请参阅下面的“类型”一节铸件)。
请注意,您只应提供:switches
或:strict
选项。如果您同时提供,ArgumentError
则会引发异常。
类型
通过解析的开关OptionParser
可能需要零个或一个参数。
下列开关类型不带参数:
:boolean
- 将该值设置为true
给定时间(另请参见下面的“否定开关”部分)
:count
-计数开关给定的次数
以下开关采用一个参数:
:integer
-将值解析为整数
:float
-将值解析为浮点数
:string
-将值解析为字符串
如果不能根据给定类型解析开关,则在无效选项列表中返回开关。
修饰符
开关可以用修饰符指定,这会改变它们的行为。支持以下修饰符:
- :keep - 保留重复项目而不是覆盖它们; 适用于所有类型,除了:count。指定switch_name: :keep假定的类型:switch_name将是:string。要使用:keep除以外的类型:string,请使用列表作为交换机的类型。例如:[foo: [:integer, :keep]].Newation开关如果开关SWITCH被指定为具有类型:boolean,那么它也可以被传递,--no-SWITCH并将其设置为false:iex> OptionParser.parse([“ - no-op”,“path / to / file “],开关:[op::boolean]){[op:false],[”path / to / file“],[]}解析动态开关OptionParser还包括一个动态模式,它将尝试动态解析开关。这可以通过不指定:switchesor 来完成:strictoption.iex> OptionParser.parse([“ - debug”]){[debug:true],[],[]}开关后跟一个值将被赋值为一个字符串。没有参数的开关(如--debug上面的示例中所示)将自动设置为true。由于Elixir将开关转换为原子,因此动态模式只会解析转换为运行时使用的原子的开关。因此,下面的代码可能不会解析给定的选项,因为:option_parser_example原子从来没有在任何地方使用过:OptionParser.parse([“ - option-parser-example”])#下面任何地方都没有使用:option_parser_example原子但是,代码以下是自从:option_parser_example原子在稍后(或更早)的某个点使用:{opts,_,_} = OptionParser.parse([“ - option-parser-example”])opts [:option_parser_example]换句话说,当使用动态模式,Elixir会做正确的事情,只解析运行时使用的选项,忽略所有其他选项。如果你想解析所有的开关,不管它们是否存在,你都可以通过allow_nonexistent_atoms: true作为选项传递来强制创建原子。当您构建接收动态命名参数的命令行应用程序时,此类选项非常有用,但在长时间运行的系统中必须小心使用。开关后跟一个值将以字符串形式赋值。没有参数的开关(--debug如上例所示)将自动设置为true.Aliases一组别名可以在:aliases{parsed,argv} | no_return相同parse/2但OptionParser.ParseError如果给出任何无效选项则会引发异常。如果没有错误,则返回一个{parsed, rest}元组,其中:
parsed
是解析开关的列表(与in相同parse/2
)
rest
是参数列表(与in相同parse/2
)
实例
iex> OptionParser.parse!(["--debug", "path/to/file"], strict: [debug: :boolean])
{[debug: true], ["path/to/file"]}
iex> OptionParser.parse!(["--limit", "xyz"], strict: [limit: :integer])
** (OptionParser.ParseError) 1 error found!
--limit : Expected type integer, got "xyz"
iex> OptionParser.parse!(["--unknown", "xyz"], strict: [])
** (OptionParser.ParseError) 1 error found!
--unknown : Unknown option
iex> OptionParser.parse!(["-l", "xyz", "-f", "bar"],
...> switches: [limit: :integer, foo: :integer], aliases: [l: :limit, f: :foo])
** (OptionParser.ParseError) 2 errors found!
-l : Expected type integer, got "xyz"
-f : Expected type integer, got "bar"
parse_head(argv, opts \ [])
parse_head(argv, options) :: {parsed, argv, errors}
类似,parse/2
但只解析头部argv
; 只要发现一个非开关,它就会停止解析。
查看parse/2
更多信息。
例
iex> OptionParser.parse_head(["--source", "lib", "test/enum_test.exs", "--verbose"],
...> switches: [source: :string, verbose: :boolean])
{[source: "lib"], ["test/enum_test.exs", "--verbose"], []}
iex> OptionParser.parse_head(["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"],
...> switches: [source: :string, verbose: :boolean, unlock: :boolean])
{[verbose: true, source: "lib"], ["test/enum_test.exs", "--unlock"], []}
parse_head!(argv, opts \ [])
parse_head!(argv, options) :: {parsed, argv} | no_return
一样parse_head/2
,但提出了一个OptionParser.ParseError
如果给出任何无效选项例外。
如果没有错误,则返回{parsed, rest}
元组:
parsed
是解析开关的列表(与in相同parse_head/2
)
rest
是参数列表(与in相同parse_head/2
)
实例
iex> OptionParser.parse_head!(["--source", "lib", "path/to/file", "--verbose"],
...> switches: [source: :string, verbose: :boolean])
{[source: "lib"], ["path/to/file", "--verbose"]}
iex> OptionParser.parse_head!(["--number", "lib", "test/enum_test.exs", "--verbose"],
...> strict: [number: :integer])
** (OptionParser.ParseError) 1 error found!
--number : Expected type integer, got "lib"
iex> OptionParser.parse_head!(["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"],
...> strict: [verbose: :integer, source: :integer])
** (OptionParser.ParseError) 2 errors found!
--verbose : Missing argument of type integer
--source : Expected type integer, got "lib"
split(string)
split(String.t) :: argv
将字符串拆分成argv/0
块。
这个函数string
以类似许多shell的方式将给定的字符串分割成一个字符串列表。
实例
iex> OptionParser.split("foo bar")
["foo", "bar"]
iex> OptionParser.split("foo \"bar baz\"")
["foo", "bar baz"]
to_argv(enum, opts \ [])
to_argv(Enumerable.t, options) :: argv
接收可枚举的键值并将其转换为argv/0
。
钥匙一定是原子。带钥匙nil
值被丢弃,布尔值被转换为--key
或--no-key
%28如果值为true
或false
,分别为%29和所有其他值都将使用Kernel.to_string/1
...
建议把它转到to_argv/2
同一组options
给予parse/2
.某些开关只能使用switches
手头有信息。
实例
iex> OptionParser.to_argv([foo_bar: "baz"])
["--foo-bar", "baz"]
iex> OptionParser.to_argv([bool: true, bool: false, discarded: nil])
["--bool", "--no-bool"]
一些交换机将根据开关标志输出不同的值:
iex> OptionParser.to_argv([number: 2], switches: [])
["--number", "2"]
iex> OptionParser.to_argv([number: 2], switches: [number: :count])
["--number", "--number"]