args.d | a command line argument and config file parser

Robert burner Schadek via Digitalmars-d-announce digitalmars-d-announce at puremagic.com
Wed Aug 2 00:29:42 PDT 2017


On Tuesday, 1 August 2017 at 17:46:57 UTC, H. S. Teoh wrote:
> I think UDA-driven configuration parsing is ultimately the 
> right direction to go.  And by that I mean more than just 
> command-line parsing, but the parsing of configuration 
> parameters in general, including command-line options, 
> configuration files, etc..  Usually a lot of boilerplate is 
> involved in constructing a parser, enumerating options, then 
> mapping that to configuration variables, adding helpful 
> descriptions, etc.. All of which are a maintenance burden on 
> the programmer, because any of these components can become 
> out-of-sync with each other: the parsing of parameters, the 
> mapping of these parameters to internal variables, and the help 
> text.

args.d uses the same parser for command line options and for the 
config file.
The parser gets adapted between the two with some compile time 
parameters.

>
> With UDAs, it's possible to unify all three in one declaration, 
> thereby ensuring things will never go out-of-sync, and also 
> greatly reduces the amount of boilerplate the programmer has to 
> type.
>
> I didn't look too closely at args.d yet, but in my 
> implementation, I have UDAs for specifying alternate names for 
> common configuration parameters (e.g., "outfile=..." instead of 
> "outputFilename=..."). This allows more user-friendly option 
> names, and also decouples it from internal variable naming 
> schemes.

I found that good variable names make good command line option 
names.
And you remove one indirection, which I always like.
Plus, you can always use short options, which are checked for 
uniqueness at compile time by args.d.

>
> There's also UDAs for optionally flattening a nested struct, so 
> that internally I can have separate structs for configuring 
> each module, but the main program combines all of them into a 
> single flattened struct, so that to the user all the options 
> are top-level (can specify "outfile=..." instead of 
> "backend.outputFilename=..."). The user shouldn't need to know 
> how the program is organized internally, after all, yet I can 
> still properly encapsulate configuration parameters relevant to 
> only that module, thereby avoiding spaghetti dependencies of 
> modules on a single global configuration struct.

I thought about that as well, but didn't do it because if found:

--mysql.ipAddress      Type: string   default: localhost       
Help:
--redis.ipAddress      Type: string   default: localhost       
Help:

looks and works just awesome.
At least better than --mysqlipAddress and --redisipAddress.




More information about the Digitalmars-d-announce mailing list