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

Viewed 155

Python's click module have choice-options, when the input is invalid:

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()

the script above will exit when the user input invalid choice, and it print out the valid choices for you, which is convenient.

I try to rewrite it in Raku:

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

When offter an invalid choice, Raku just output the Usage, which is less awesome:

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

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

2 Answers
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

By making MAIN a multi sub:

# 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";
}

Note that the second MAIN candidate has is hidden-from-USAGE because we don't want to see that candidate listed in any USAGE message. Also note that the second MAIN candidate has the hash_type argument as mandatory, by specifying the !.

If you have more candidates, you will probably need to take care of any additional named arguments in the second candidate.

EDIT: wamba's answer is better. Still leaving my answer here as it may introduce people to the concept of using multi subs for MAIN, and of using the is hidden-from-USAGE trait.

Related