当前位置: 首页>>编程示例 >>用法及示例精选 >>正文


Elixir OptionParser.parse用法及代码示例

Elixir语言中 OptionParser.parse 相关用法介绍如下。

用法:

parse(argv, opts \\ [])
@spec parse(argv(), options()) :: {parsed(), argv(), errors()}

argv 解析为关键字列表。

它返回一个 three-element 元组,其形式为 {parsed, args, invalid} ,其中:

  • parsed 是已解析开关的关键字列表,其中包含 {switch_name, value} 元组; switch_name 是表示开关名称的原子,而 value 是根据 opts 解析的该开关的值(有关更多信息,请参见 "Examples" 部分)
  • argsargv 中剩余参数的列表作为字符串
  • invalid 是作为 {option_name, value} 的无效选项列表,其中 option_name 是原始选项,如果选项不是预期的,则 valuenil,如果值不具有预期类型,则为字符串值对于相应的选项

Elixir 将开关转换为带下划线的原子,因此 --source-path 变为 :source_path 。这样做是为了更好地适应 Elixir 约定。但是,这意味着开关不能包含下划线,并且包含下划线的开关总是会在无效开关列表中返回。

解析时,通常会列出开关及其预期类型:

iex> OptionParser.parse(["--debug"], strict: [debug: :boolean])
{[debug: true], [], []}

iex> OptionParser.parse(["--source", "lib"], strict: [source: :string])
{[source: "lib"], [], []}

iex> OptionParser.parse(
...>   ["--source-path", "lib", "test/enum_test.exs", "--verbose"],
...>   strict: [source_path: :string, verbose: :boolean]
...> )
{[source_path: "lib", verbose: true], ["test/enum_test.exs"], []}

我们将在下面探索选项解析器的有效开关和操作模式。

选项

支持以下选项:

  • :switches:strict - 请参阅下面的 "Switch definitions" 部分
  • :allow_nonexistent_atoms - 请参阅下面的“解析未知开关”部分
  • :aliases - 请参阅下面的 "Aliases" 部分

开关定义

可以通过以下两个选项之一指定开关:

  • :strict - 定义严格开关及其类型。 argv 中未在列表中指定的任何开关都将在无效选项列表中返回。这是解析选项的首选方式。

  • :switches - 定义开关及其类型。此函数仍会尝试解析不在此列表中的开关。

这两个选项都接受一个关键字列表,其中键是定义开关名称的原子,值是开关的type(有关更多信息,请参见下面的"Types" 部分)。

请注意,您应该只提供:switches:strict 选项。如果两者都提供,则会引发 ArgumentError 异常。

类型

OptionParser 解析的开关可以采用零个或一个参数。

以下开关类型不带参数:

  • :boolean - 在给定时将值设置为 true(另请参见下面的 "Negation switches" 部分)
  • :count - 计算给定开关的次数

以下开关采用一个参数:

  • :integer - 将值解析为整数
  • :float - 将值解析为浮点数
  • :string - 将值解析为字符串

如果无法根据给定类型解析开关,则在无效选项列表中返回。

修饰符

可以使用修饰符指定开关,这会改变它们的行为方式。支持以下修饰符:

  • :keep - 保留重复的元素而不是覆盖它们;适用于除 :count 之外的所有类型。指定 switch_name: :keep 假定 :switch_name 的类型将为 :string

要将 :keep:string 以外的类型一起使用,请使用列表作为开关的类型。例如:[foo: [:integer, :keep]]

否定开关

如果开关 SWITCH 被指定为具有类型 :boolean ,它也可以作为 --no-SWITCH 传递,这会将选项设置为 false

iex> OptionParser.parse(["--no-op", "path/to/file"], switches: [op: :boolean])
{[op: false], ["path/to/file"], []}

解析未知开关

当给出:switches 选项时, OptionParser 将尝试解析未知开关:

iex> OptionParser.parse(["--debug"], switches: [key: :string])
{[debug: true], [], []}

即使我们没有在开关列表中指定--debug,它也是返回选项的一部分。这也可以:

iex> OptionParser.parse(["--debug", "value"], switches: [key: :string])
{[debug: "value"], [], []}

后跟一个值的开关将被分配该值,作为一个字符串。没有参数的开关将自动设置为 true 。由于我们无法断言开关值的类型,因此最好使用 :strict 选项,它只接受已知开关并始终验证它们的类型。

如果您确实想解析未知开关,请记住 Elixir 将开关转换为原子。由于原子不是garbage-collected,OptionParser 将仅解析转换为运行时使用的原子的开关以避免泄漏原子。例如,下面的代码将丢弃 --option-parser-example 开关,因为 :option_parser_example 原子从未在任何地方使用:

OptionParser.parse(["--option-parser-example"], switches: [debug: :boolean])
# The :option_parser_example atom is not used anywhere below

但是,只要稍后(或更早)在同一模块中的某个时间点使用 :option_parser_example atom,下面的代码就可以工作。例如:

{opts, _, _} = OptionParser.parse(["--option-parser-example"], switches: [debug: :boolean])
# ... then somewhere in the same module you access it ...
opts[:option_parser_example]

换句话说,Elixir 只会解析运行时使用的选项,而忽略所有其他选项。如果您想解析所有开关,无论它们是否存在,您可以通过传递allow_nonexistent_atoms: true 作为选项来强制创建原子。请谨慎使用此选项。它仅在您构建接收dynamically-named 参数的命令行 应用程序时有用,并且必须在long-running 系统中避免使用。

别名

可以在 :aliases 选项中指定一组别名:

iex> OptionParser.parse(["-d"], aliases: [d: :debug], strict: [debug: :boolean])
{[debug: true], [], []}

例子

以下是使用不同类型和修饰符的一些示例:

iex> OptionParser.parse(["--unlock", "path/to/file"], strict: [unlock: :boolean])
{[unlock: true], ["path/to/file"], []}

iex> OptionParser.parse(
...>   ["--unlock", "--limit", "0", "path/to/file"],
...>   strict: [unlock: :boolean, limit: :integer]
...> )
{[unlock: true, limit: 0], ["path/to/file"], []}

iex> OptionParser.parse(["--limit", "3"], strict: [limit: :integer])
{[limit: 3], [], []}

iex> OptionParser.parse(["--limit", "xyz"], strict: [limit: :integer])
{[], [], [{"--limit", "xyz"}]}

iex> OptionParser.parse(["--verbose"], switches: [verbose: :count])
{[verbose: 1], [], []}

iex> OptionParser.parse(["-v", "-v"], aliases: [v: :verbose], strict: [verbose: :count])
{[verbose: 2], [], []}

iex> OptionParser.parse(["--unknown", "xyz"], strict: [])
{[], ["xyz"], [{"--unknown", nil}]}

iex> OptionParser.parse(
...>   ["--limit", "3", "--unknown", "xyz"],
...>   switches: [limit: :integer]
...> )
{[limit: 3, unknown: "xyz"], [], []}

iex> OptionParser.parse(
...>   ["--unlock", "path/to/file", "--unlock", "path/to/another/file"],
...>   strict: [unlock: :keep]
...> )
{[unlock: "path/to/file", unlock: "path/to/another/file"], [], []}

相关用法


注:本文由纯净天空筛选整理自elixir-lang.org大神的英文原创作品 OptionParser.parse(argv, opts \\ [])。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。