New library: argparse, for parsing CLI arguments

Steven Schveighoffer schveiguy at gmail.com
Wed Oct 13 16:24:52 UTC 2021


On 10/13/21 11:50 AM, Andrey Zherikov wrote:
> On Wednesday, 13 October 2021 at 14:36:30 UTC, Steven Schveighoffer wrote:
>> One nitpick -- you should be able to opt in using the name of the 
>> field member instead of having to write `@NamedArgument`. e.g. your 
>> `string unused` parameter requires a `@NamedArgument("unused")` which 
>> seems unnecessary.
> 
> I think `unused` word confuses a bit. I meant the argument that is 
> skipped in command line so it has a default value (`"some default value"`).
> So having this is totally fine:
> ```d
> struct Params
> {
>      string s;
> 
>      @NamedArgument("num")
>      int n;
> }
> 
> ```
> 
> I'll rename `unused` to remove this confusion.

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


More information about the Digitalmars-d-announce mailing list