New library: argparse, for parsing CLI arguments

WebFreak001 d.forum at webfreak.org
Wed Oct 13 18:27:46 UTC 2021


On Wednesday, 13 October 2021 at 16:24:52 UTC, Steven 
Schveighoffer wrote:
> On 10/13/21 11:50 AM, Andrey Zherikov wrote:
>> On Wednesday, 13 October 2021 at 14:36:30 UTC, Steven [...]
>
> No, it's not a confusion about `unused`. The `array` parameter 
> has the same issue.
>
> I meant that for named parameters, one shouldn't have to 
> attribute them for them to be considered part of the parameters.
>
> e.g. (to replace your current code):
>
> ```d
> struct Params
> {
>     // Positional arguments are required by default
>     @PositionalArgument(0) // override the default of a named 
> argument
>     string name;
>
>     // Named argments are optional by default
>     string unused = "some default value";
>
>     // Numeric types are converted automatically
>     int num;
>
>     // Boolean flags are supported
>     bool flag;
>
>     // Enums are also supported
>     enum Enum { unset, foo, boo };
>     @NamedArgument("enum") // required since enum is a keyword
>     Enum enumValue;
>
>     // Use array to store multiple values
>     int[] array;
>
>     // Callback with no args (flag)
>     void cb() {}
>
>     // Callback with single value
>     void cb1(string value) { assert(value == "cb-value"); }
>
>     // Callback with zero or more values
>     void cb2(string[] value) { assert(value == 
> ["cb-v1","cb-v2"]); }
> }
> ```
>
> The point is that I shouldn't have to tell the library the name 
> of something that I've already given a name to.
>
> Having them named differently on the command line than the 
> actual field name should still be a possibility (and required 
> in some cases, e.g. the `enum` case above), but honestly, the 
> `Params` struct exists solely to accept command line 
> parameters, there's no compelling need to use alternate names 
> for the command line and the field name. If the library 
> automatically does the right thing by default, then your code 
> becomes simpler and more beautiful.
>
> Not to detract from your library, because I think it's an 
> awesome design to model using structs (one I use all the time), 
> but the API developer in me frowns at lack of DRY. Try to focus 
> on requiring the smallest amount of machinery/attributes 
> possible. Every time you require extraneous pieces to get 
> things to work, it adds another place where errors/confusion 
> can happen.
>
> -Steve

This should probably rather be:


```d
struct Params
{
     // Positional arguments are required by default
     @PositionalArgument(0) // override the default of a named 
argument
     string name;

     // Named argments are optional by default
     @NamedArgument
     string unused = "some default value";

     // Numeric types are converted automatically
     @NamedArgument
     int num;

     // Boolean flags are supported
     @NamedArgument
     bool flag;

     // Enums are also supported
     enum Enum { unset, foo, boo };
     @NamedArgument("enum") // required since enum is a keyword
     Enum enumValue;

     // Use array to store multiple values
     @NamedArgument
     int[] array;

     // Callback with no args (flag)
     @NamedArgument
     void cb() {}

     // Callback with single value
     @NamedArgument
     void cb1(string value) { assert(value == "cb-value"); }

     // Callback with zero or more values
     @NamedArgument
     void cb2(string[] value) { assert(value == 
["cb-v1","cb-v2"]); }
}
```

as otherwise the definition could be ambiguous (like are the 
parameters positional with automatic count or named by default?)

If you don't like the repetition you could also then make it 
`@NamedArgument { [all my variables] }` But I'm not a fan of 
having everything included even without UDA


More information about the Digitalmars-d-announce mailing list