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

Posted

技术标签:

【中文标题】如何从命令行提供非 slurpy 数组或命名数组?【英文标题】:How to provide a non-slurpy array or named array from the command line? 【发布时间】:2020-09-24 01:39:51 【问题描述】:

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

如果我在多调度 MAIN 中使用 slurpy 参数,这将被识别并完美运行:

multi MAIN( 'config', 'add', *@hostnames ) 

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

multi MAIN( 'config', 'add', @hostnames ) 

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

$ 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

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

我也尝试使用数组作为命名参数:

my %*SUB-MAIN-OPTS = :named-anywhere;
multi MAIN( 'config', 'add', :@hostnames) 

鉴于raku docs 中的示例,我希望这可以工作:

$ cli.raku config add --hostnames=www.example.com example.com

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

【问题讨论】:

对于命名参数,我认为您多次给出该选项:—host=a —host=b 这里的主要问题是,有一个带有数组作为参数的 MAIN 期望由它的调用者处理一个数组,并且 shell 不可能做那种事情(参见here,所以你只剩下slurpy了。逗号没有区别。也许我们应该在文档中澄清这一点,但无论如何,这是一个shell限制,而不是Raku的 【参考方案1】:

Raku 中内置的 arg 解析对应于标准 shell 功能/约定。正如 JJ 所指出的,单个阵列没有外壳功能/约定。我想这就是为什么普通的@foo(和%bar)没有被定义为匹配任何东西作为内置CLI解析功能的一部分。


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

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

multi MAIN( 'config', 'add', *@hostnames where +*) 

您可以将+* 解读为“一个或多个”。

实际情况是我写了一个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

在 SO 中搜索"[raku] getopt"


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

A Raku getopt implementation

SuperMAIN, a strict superset of the built in MAIN functionality.

“我在生产环境中构建命令行应用程序的经验”(video、slides)

【讨论】:

@jjmerelo 提到的单个数组没有 shell 约定澄清了很多。 在 SuperMain 源代码中,你指给我看,我发现:PROCESS:: = True;这允许我将子命令放在命名数组的前面。 (也许可以添加到docs.raku.org/language/create-cli#index-entry-$PERCENT_SIGN*SUB-MAIN-OPTS) 也感谢 Brian Duggan 的视频和演示,内容非常丰富! 没问题@raiph。发表了这个问题:Alter how arguments are processed before they're passed to sub MAIN 请注意,重复命名参数的 Raku 约定与 bash、zsh 等中存在的大括号扩展功能结合使用效果很好。对于答案末尾的示例,这可以从启用该功能的那些外壳:cli-prog.raku --n=www.example.com,example.com,other.url,even-more.org

以上是关于如何从命令行提供非 slurpy 数组或命名数组?的主要内容,如果未能解决你的问题,请参考以下文章

在 psql 命令行上传递数组参数

提供整数数组作为命令行的输入

如何使用 Scala 从 Spark 中的列表或数组创建行

Redis中如何操作List数组

如何使用作曲家从命令行添加非公共存储库?

从命令行参数指定数组