digitalmars.D.learn - pragma msg field name?
- Chris Katko (23/23) Jun 26 2023 inside a static foreach I can do
- =?UTF-8?Q?Ali_=c3=87ehreli?= (22/23) Jun 26 2023 I know .tupleof, which you can typeof() as well:
- Chris Katko (53/76) Jun 26 2023 That seems to do the trick, I was really not expecting so much
- Chris Katko (50/50) Jun 27 2023 Does anyone know why the new variables don't show up after the
- Adam D Ruppe (10/11) Jun 27 2023 D's declarations are all order-independent, in theory those
- Chris Katko (10/21) Jun 27 2023 Thank you, that's what I thought, but then I started adding them
- Steven Schveighoffer (10/15) Jun 27 2023 In particular the practice of adding new members based on introspecting
- Jonathan M Davis (17/40) Jun 26 2023 Well, on my machine, once the import for std.traits is added, that code
- Dennis (4/6) Jun 27 2023 For some time now, it accepts any number of objects, which will
- Adam D Ruppe (3/5) Jun 27 2023 It is the same as if you wrote `Class.field`
inside a static foreach I can do ``` enum rep; class myObject{ int field1, field2, field3; static foreach(field; getSymbolsByUDA!(typeof(this), rep)) { pragma(msg, field); // fails pragma(msg, fullyQualifiedName!field); // works } } ``` error for pragma(msg, field) ``` source/app.d(33,16): Error: value of `this` is not known at compile time source/app.d(33,4): while evaluating `pragma(msg, field)` [repeating for every variable in the class] ``` How do I get just the field name? And why does it think this is a run-time value? I need to wrap it in some sort of template? All I see in std.traits docs are: fullyQualifiedName mangledName moduleName packageName
Jun 26 2023
On 6/26/23 21:25, Chris Katko wrote:How do I get just the field name?I know .tupleof, which you can typeof() as well: class myObject{ int field1, field2, field3; static foreach(field; typeof(this).tupleof) { pragma(msg, field.stringof); } static foreach(MemberType; typeof(typeof(this).tupleof)) { pragma(msg, MemberType); } } The output: field1 field2 field3 int int int I had to consult what I wrote years ago: http://ddili.org/ders/d.en/tuples.html#ix_tuples..tupleof Ali
Jun 26 2023
On Tuesday, 27 June 2023 at 04:56:19 UTC, Ali Çehreli wrote:On 6/26/23 21:25, Chris Katko wrote:That seems to do the trick, I was really not expecting so much text just to get something so simple! At the moment I'm trying to take variables with an attribute (rep) and then make a duplicate of them inside the struct. It seems to work. If I had duplicate names, it fails. However, the new fields don't appear to be showing up on a second enumeration: enum rep; struct multiplayerObject2 { rep ushort type; ("rep2") ushort type2; float x, y; static foreach(t; typeof(this).tupleof) { // no if rep/rep2 here, i'm just testing: pragma(msg, t.stringof); // does not see any new fields! mixin("bool " ~ t.stringof ~ "25;"); // copy the fieldname with a suffix } pragma(msg, "-----separator-----"); static foreach(t; typeof (this).tupleof) // again { pragma(msg, t.stringof); // does not see any new fields! } } output ``` type type2 x y -----separator----- type type2 x y ``` However, if I do try to force the names to duplicate (say "type2") I get an error involving some sort of __anonymous subobject. ``` source/app.d-mixin-123(123,6): Error: variable `app.multiplayerObject2.__anonymous.type2` conflicts with variable `app.multiplayerObject2.type2` at source/app.d(116,19) ``` I also never realized you could put a static/static foreach inside the body of a struct (and not a function) so I'm still having trouble wrapping my head around that. Is it processing top-down? Jonathan M Davis: Yeah, it does what I listed if you add the UDA to it.How do I get just the field name?I know .tupleof, which you can typeof() as well: class myObject{ int field1, field2, field3; static foreach(field; typeof(this).tupleof) { pragma(msg, field.stringof); } static foreach(MemberType; typeof(typeof(this).tupleof)) { pragma(msg, MemberType); } } The output: field1 field2 field3 int int int I had to consult what I wrote years ago: http://ddili.org/ders/d.en/tuples.html#ix_tuples..tupleof Ali
Jun 26 2023
Does anyone know why the new variables don't show up after the static foreach? I have a struct, it has some marked fields. I want to note those fields at compile time and make some similarly named fields like myField becomes myField__replicated. The code doesn't _have_ to be inside the struct/class itself. It could be: ``` auto replicatedObject = makeReplicated!(myObject); ``` for example. I'm not sure the high-level best way right now, as I'm currently having issues with the nitty-gritty implementation of templates. snippetcode (drop right into run.dlang.io): ```D import std; struct multiplayerObject2 { ushort type; ushort type2; float x, y; static foreach(t; typeof(this).tupleof) { pragma(msg, t.stringof); mixin("bool " ~ t.stringof ~ "25;"); // copy the fieldname with a suffix } pragma(msg, "-----separator-----"); static foreach(t; typeof (this).tupleof) // again { pragma(msg, t.stringof); // does not see any new fields! } } void main() { } ``` ```D // Output type type2 x y -----separator----- type type2 x y ```
Jun 27 2023
On Tuesday, 27 June 2023 at 22:20:22 UTC, Chris Katko wrote:pragma(msg, t.stringof); // does not see any new fields!D's declarations are all order-independent, in theory those foreaches are done simultaneously, so it is kinda a race condition. In practice, the compiler does them in two passes but both based on the same initial state. Adding stuff and then reflecting over the stuff you add must be done as explicit steps on the outside, like you can make a `struct step1 {}` then `alias step2 = transform!step1;` then `alias step3 = transform_again!step2;` or something.
Jun 27 2023
On Tuesday, 27 June 2023 at 22:34:17 UTC, Adam D Ruppe wrote:On Tuesday, 27 June 2023 at 22:20:22 UTC, Chris Katko wrote:Thank you, that's what I thought, but then I started adding them and there was no warning and I was like "wait... is this top-down???"pragma(msg, t.stringof); // does not see any new fields!D's declarations are all order-independent, in theory those foreaches are done simultaneously, so it is kinda a race condition.In practice, the compiler does them in two passes but both based on the same initial state. Adding stuff and then reflecting over the stuff you add must be done as explicit steps on the outside, like you can make a `struct step1 {}` then `alias step2 = transform!step1;` then `alias step3 = transform_again!step2;` or something.Okay again makes more sense. The amount of stuff that was "kinda" working, plus learning through tiny 3 liner code snippets in docs, was making my brain explode a bit. A constructor/factory pattern for this makes way more sense. Sometimes it's hard to tell where things are symbolic / functional, verses procedural/linear.
Jun 27 2023
On 6/27/23 6:34 PM, Adam D Ruppe wrote:On Tuesday, 27 June 2023 at 22:20:22 UTC, Chris Katko wrote:In particular the practice of adding new members based on introspecting other members is suspect. I've done it too, but I think it probably would be better if we didn't allow this kind of stuff, or came up with a sane way to do this. This leads to all kinds of weird stuff. Like if you instantiate a template with the current type being compiled, that template is locked to that type *at that point in compilation*. Then you look at it outside the type, and the value is already cached. -Stevepragma(msg, t.stringof); // does not see any new fields!D's declarations are all order-independent, in theory those foreaches are done simultaneously, so it is kinda a race condition.
Jun 27 2023
On Monday, June 26, 2023 10:25:13 PM MDT Chris Katko via Digitalmars-d-learn wrote:inside a static foreach I can do ``` enum rep; class myObject{ int field1, field2, field3; static foreach(field; getSymbolsByUDA!(typeof(this), rep)) { pragma(msg, field); // fails pragma(msg, fullyQualifiedName!field); // works } } ``` error for pragma(msg, field) ``` source/app.d(33,16): Error: value of `this` is not known at compile time source/app.d(33,4): while evaluating `pragma(msg, field)` [repeating for every variable in the class] ``` How do I get just the field name? And why does it think this is a run-time value? I need to wrap it in some sort of template? All I see in std.traits docs are: fullyQualifiedName mangledName moduleName packageNameWell, on my machine, once the import for std.traits is added, that code compiles but prints nothing, so I suspect that you paired it down too much (likely related to the fact that none of the fields in question actually have UDAs on them). However, I would point out that getSymbolsByUDA gives you symbols, not strings, whereas pragma(msg, ...) wants a string. fullyQualifiedName works, because it results in a string. You can see what field is by using typeof on it, but presumably, it's complaining about being a runtime value, because when you use it, it's trying to evaluate the symbol (e.g. get the value of field1). Using .stringof on field will give you a string, though I don't know if it'll give you what you're looking for. In general, FieldNameTuple would probably be what you would want for getting the names of the fields in a struct or class, though obviously, that wouldn't be just getting the ones with a specific UDA. - Jonathan M Davis
Jun 26 2023
On Tuesday, 27 June 2023 at 05:03:01 UTC, Jonathan M Davis wrote:However, I would point out that getSymbolsByUDA gives you symbols, not strings, whereas pragma(msg, ...) wants a string.For some time now, it accepts any number of objects, which will all be converted to strings and concatenated to form the message. The same applies to `static assert()`.
Jun 27 2023
On Tuesday, 27 June 2023 at 04:25:13 UTC, Chris Katko wrote:How do I get just the field name?__traits(identifier, field)And why does it think this is a run-time value?It is the same as if you wrote `Class.field`
Jun 27 2023