On Mon, Aug 03, 2020 at 08:16:57PM -0700, Ali Çehreli via Digitalmars-d-learn wrote: [...] > UDAs were added to D by a request from Manu Evans and that's when I > learned them. In one of Manu's use cases they would put a @Tweakable > attribute to certain struct members. The effect of that attribute > would be to compile special code that would expose that member in a > dialog box where the developer would "tweak" its value to see how the > program (a game) would behave at specific values of that member. > > The awesomeness comes from the fact that once they have this > @Tweakable machinery, they don't change their code at all: They put > that attribute to certain members during development, find good values > and then remove it; perhaps in half an hour. The only addition to code > is one @Tweakable attribute and some magic produces a dialog box; then > they remove the attribute. Pretty cool. :)
I've also used it for generating getopt-like code for parsing command-line parameters. You might have several subsystems in your program, each of which comes with a set of parameters that can be configured; instead of sprinkling this information across multiple places (once in the subsystem to read the values, once in the call to getopt to parse the option, once in the code for display detailed description of the setting, once in configuration file parsing code to basically do the same thing as getopt except with a config file, ad nauseaum), just create a struct that contains the parameters for each subsystem, then use UDAs to decorate each setting with command-line option name, help text, value ranges, or even custom parsing functions if you want to get fancy. Then write a generic option-parsing function that introspects the UDAs to generate help text, option names, default values, precedences, etc.. Another generic function for parsing the config file. Then the next time you want to add a setting, it's just a matter of adding another field to your struct, tag it with the appropriate UDAs, and it will "magically" appear in your command-line, config file parsing, and in-program help text without further ado. Best of all, once you build this infrastructure, you can easily reuse it across different programs: the getopt wrapper, help text generator, config file parser are all completely driven by introspection and UDAs, so there's nothing program-specific about them. Just copy-n-paste them into another project, and create your structs, and you're all set. :-) T -- "I'm not childish; I'm just in touch with the child within!" - RL
