如果来自命令行的输入值不在 MAIN 例程中的有效选择列表中,如何获得更好的错误提示?

How to get better error prompt if the input value from command line not in a list of valide choice in the MAIN routine?

Python的click模块有选择选项,输入无效时:

import click

@click.command()
@click.option('--hash-type',
              type=click.Choice(['MD5', 'SHA1'], case_sensitive=False))

def digest(hash_type):
    click.echo(hash_type)

# python demo.py --hash-type=HASH256
# Error: Invalid value for '--hash-type': 'HASH256' is not one of 'MD5', 'SHA1'.
if __name__=="__main__":
    digest()

上面的脚本会在用户输入无效选项时退出,并打印出有效的选项给你,方便。

我尝试用 Raku 重写它:

# raku demo.raku --hash_type=HASH256
sub MAIN(
    :$hash_type where * ∈ ['MD5', 'SHA1'], #= the hash code
) {
    say $hash_type;
}

当做出无效选择时,Raku 只输出 Usage,这不太好:

Usage:
  demo.raku [--hash_type[=Any where { ... }]]
  --hash_type[=Any where { ... }]    the hash code

那么,如果命令行输入的值不在 MAIN 例程的有效选择列表中,如何获得更好的错误提示?

通过制作 MAIN 多子:

# raku demo.raku --hash_type=HASH256
multi sub MAIN(
  :$hash_type where * ∈ <MD5 SHA1>, #= the hash code
) {
    say "OK: $hash_type";
}
multi sub MAIN(:$hash_type!) is hidden-from-USAGE {
    say "Unrecognized hash_type: $hash_type";
}

请注意,第二个 MAIN 候选 is hidden-from-USAGE 因为我们不希望在任何 USAGE 消息中看到该候选。另请注意,第二个主要候选人通过指定 !.

hash_type 参数作为强制性参数

如果您有更多候选项,您可能需要处理第二个候选项中的任何其他命名参数。

编辑:wamba 的回答更好。仍然在这里留下我的答案,因为它可能会向人们介绍对 MAIN 使用 multi sub 和使用 is hidden-from-USAGE 特征的概念。

enum HT <MD5 SHA1>; 

sub MAIN(
    HT :$hash_type!,
) {
    say $hash_type;
}
Usage:
  -e '...' [--hash_type=<HT> (MD5 SHA1)]
  
    --hash_type=<HT> (MD5 SHA1)    the hash code