如何从命令行提供非 slurpy 数组或命名数组?

acw*_*acw 12 multiple-dispatch command-line-interface named-parameters raku

首先:raku (perl6) 很棒。克罗也是。只用了一个周末就坠入爱河。但是现在我偶然发现了一些必须非常简单的东西。

如果我在多分派 MAIN 中使用 slurpy 参数,则可以识别并完美运行:

multi MAIN( 'config', 'add', *@hostnames ) {
Run Code Online (Sandbox Code Playgroud)

但是,如果我将其设为非 slurpy 数组,则要么无法识别,要么我不知道如何从命令行提供它:

multi MAIN( 'config', 'add', @hostnames ) {
Run Code Online (Sandbox Code Playgroud)

我希望这些调用之一能够工作:

$ cli.raku config add www.example.com example.com
$ cli.raku config add www.example.com,example.com
$ cli.raku config add www.example.com, example.com
Run Code Online (Sandbox Code Playgroud)

Cro CLI 中使用了类似的构造,但是没有示例说明如何使用文档中的数组调用其中一个命令。

我也用一个数组作为命名参数尝试了这个:

my %*SUB-MAIN-OPTS = :named-anywhere;
multi MAIN( 'config', 'add', :@hostnames) {
Run Code Online (Sandbox Code Playgroud)

鉴于raku 文档中的示例,我希望它可以工作:

$ cli.raku config add --hostnames=www.example.com example.com
Run Code Online (Sandbox Code Playgroud)

但它没有,也没有逗号或空格逗号分隔的变体。在所有情况下,我都会获得使用信息。

rai*_*iph 10

Raku 中内置的 arg 解析对应于标准 shell 功能/约定。正如 JJ 所指出的,单个数组没有 shell 功能/约定。我认为这就是为什么没有定义plain @foo(和%bar) 作为内置 CLI 解析功能的一部分来匹配任何内容。


您的示例将被 slurpy 覆盖,而您还没有说明为什么不想使用 slurpy。

一种猜测是,这是因为 slurpy 将允许零参数。这是解决此问题的惯用方法:

multi MAIN( 'config', 'add', *@hostnames where +*) {
Run Code Online (Sandbox Code Playgroud)

您可以将其读+*作“一个或多个”。

实际发生的事情是我写了一个where条款。除了任何其他约束(例如类型)之外,这是对变量或参数施加的约束。甲where子句是任意条件,即评估为TrueFalse。将要绑定到变量/参数的值(如果它通过约束条件)对于条件来说是隐式“它”。

每当表达式包含一个或多个运算符与一个或多个*作为操作数的 s 组合时,Raku 会将表达式转换为函数,其中*(s)是该函数的参数。

所以+*是一个小小的一个参数的函数,仅仅适用于一个前缀+到它的一个参数又名“它”。

当您将前缀+应用于数组时,它会返回该Int数组中元素的计数。从条件表达式返回的值被评估为Bool--TrueFalse。如果是0(即没有传递参数),则返回约束条件,False因此MAIN签名无法绑定并显示使用消息。


如果不是这样,也许是因为最后每个命令行只能使用一个数组 slurpy。

或者只是好奇。


命名数组的工作方式如下:

sub MAIN ( :@n ) {}

my shell prompt> cli-prog.raku -n=www.example.com -n=example.com
Run Code Online (Sandbox Code Playgroud)

搜索“[raku] getopt”的 SO


您可以接管 CLI 解析的控制以获得您想要的任何结果: