首页
学习
活动
专区
工具
TVP
发布

选择分析器 | 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/2parse_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是原始选项valuenil如果不期望的选项被或字符串值,如果值不具有相应的选项预期的类型

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/2OptionParser.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如果值为truefalse,分别为%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"]

扫码关注腾讯云开发者

领取腾讯云代金券