digitalmars.D.learn - How to get only the field name from an alias?
- Elfstone (51/51) Feb 20 2023 I'm experimenting on a serializer design. The idea includes a
- ryuukk_ (60/60) Feb 20 2023 I'm not sure what the solution is for your specific question, but
- Elfstone (11/15) Feb 20 2023 This is super neat, but the order of the fields will have to be
- Adam D Ruppe (6/7) Feb 21 2023 You almost never want to use .stringof, instead try
- Elfstone (3/11) Feb 22 2023 Thanks, Adam! Didn't know such a trait existed and that it could
I'm experimenting on a serializer design. The idea includes a shorthand for processing a field and its attributes with an alias. But I'm not sure whether I can gather enough information from it, such as the name of the field. apparently F.stringof stands for "this.\<fieldname\>" in this context. So how can I get only the field's name? And is it possible to check if F is a field? -- In a well defined manner. import std.stdio; void processField(alias F)(Serializer sz) // is field? { writeln("attrs ", __traits(getAttributes, F)); // OK writeln(F.stringof); // "this.intField" sz.process(F.stringof, F); // "serializing int this.intField: 0" } class Serializer { void process(string k, ref int v) { writeln("serializing int ", k, ": ", v); } void process(string k, ref long v) { writeln("serializing long ", k, ": ", v); } void process(U)(ref U v) if (is(U == struct)) { v.serialize(this); } } struct OldName { string name; } struct Serializable { OldName("ifield") int intField; void serialize(Serializer sz) { sz.processField!intField(); } } void main() { import std.stdio; import std.traits; import core.internal.traits; Serializable v; auto sz = new Serializer(); sz.process(v); }
Feb 20 2023
I'm not sure what the solution is for your specific question, but there is some alternative way you could do: (no longer need function on your struct) I tried to comment the lines, even thought i'm not sure i remember everything correctly, but it compiles :p More info: https://dlang.org/spec/traits.html ```D import std.stdio; class Serializer { void process(string k, ref int v) { writeln("serializing int ", k, ": ", v); } void process(string k, ref long v) { writeln("serializing long ", k, ": ", v); } void process(U)(ref U v) if (is(U == struct)) { // get all members from U static foreach (member; __traits(allMembers, U)) { // get attributes from U.member static foreach (attr; __traits(getAttributes, __traits(getMember, U, member))) { // is the attribute OldName static if (is(typeof(attr) == OldName)) { // the name you put in OldName attribute string oldName = attr.name; auto value = __traits(getMember, v, member); writeln("field: ", member); writeln("oldname: ", oldName); writeln("value: ", value); } } } } } struct OldName { string name; } struct Serializable { OldName("ifield") int intField; } void main() { import std.stdio; import std.traits; import core.internal.traits; Serializable v; auto sz = new Serializer(); sz.process(v); } ```
Feb 20 2023
On Tuesday, 21 February 2023 at 03:13:38 UTC, ryuukk_ wrote:I'm not sure what the solution is for your specific question, but there is some alternative way you could do: (no longer need function on your struct) [...]This is super neat, but the order of the fields will have to be frozen, and I won't be able to do something like this: sz.processField!hasData(); if (this.hasData) { sz.processField!data(); } Unless I can mark versions and dependencies with attributes and analyse them somehow. The Deserializer shares the same interface by the way.
Feb 20 2023
On Tuesday, 21 February 2023 at 02:41:34 UTC, Elfstone wrote:apparently F.stringofYou almost never want to use .stringof, instead try __traits(identifier, F) and see what it gives you. Alternatively, loop over __traits(allMembers) which gives you the member names and pass that down. You can pull all the info out of allMembers with getMember and then other things to filter it out.
Feb 21 2023
On Tuesday, 21 February 2023 at 12:32:51 UTC, Adam D Ruppe wrote:On Tuesday, 21 February 2023 at 02:41:34 UTC, Elfstone wrote:Thanks, Adam! Didn't know such a trait existed and that it could work for aliases.apparently F.stringofYou almost never want to use .stringof, instead try __traits(identifier, F) and see what it gives you. Alternatively, loop over __traits(allMembers) which gives you the member names and pass that down. You can pull all the info out of allMembers with getMember and then other things to filter it out.
Feb 22 2023