Question about UDAs
H. S. Teoh
hsteoh at quickfur.ath.cx
Tue Aug 4 02:26:23 UTC 2020
On Mon, Aug 03, 2020 at 03:00:08AM +0000, Cecil Ward via Digitalmars-d-learn wrote:
> When practically speaking would you use UDAs? A real-world use-case?
There are probably more use cases than this, but for me, their primary
usefulness is in declarative programming and compile-time introspection.
Here's one specific use case: serialization. I have a bunch of structs
and classes that I want to serialize, and instead of writing tons and
tons of boilerplate, I use __traits(allMembers) to introspect a generic
type T and generate serialization code for it. But sometimes some
fields should not be serialized (e.g., they are transients like caches
and stuff). Or sometimes certain fields may need special treatment,
like a different serialization method depending on domain-specific
information about their contents.
I *could* hard-code this knowledge into the serialization code, but
UDAs provide a better alternative: I tag my types with various UDAs
recognized by the serialization system, so that when it encounters, say,
a string tagged @hexDigits, it knows that it can use a more compact
representation by parsing the string into binary and storing it as a
compact blob, for example. Or if a field should not be serialized, I'd
tag it @dontSerialize and the serialization code skips over it. By using
UDAs instead of hard-coding into the serialization code, the
serialization can be made generic and reusable across projects.
Other use cases include automatically creating database schemas based on
types: like a bunch of structs representing records, and UDAs to tag
which fields should be indexed, which fields have constraints, etc..
Then the database backend code can just introspect these types and
automatically generate schemas, query code, etc..
Since UDAs can be arbitrary types, it actually has a lot of uses. For
example, you can use them to inject code for processing data, e.g., by
using a struct as UDA with a method that takes the data and performs
some operation on it. The generic code that reads the UDA can then pass
the data to the method in a completely agnostic way that lets you
separate concerns very cleanly.
In a world without fences, who needs Windows and Gates? -- Christian Surchi
More information about the Digitalmars-d-learn