Using getSymbolsByUDA in a static foreach loop

2022-01-19 Thread Jack Stouffer via Digitalmars-d-learn
I'm trying to use getSymbolsByUDA in order to loop over all of 
the members in a struct with a certain UDA, and then call a 
function on the member. The plan is to use this to avoid looping 
over an array of function pointers.


However, the compiler is giving a strange error and the 
documentation of getSymbolsByUDA is unhelpful, as there are no 
practical use-case examples.


Here's a very simplified version of my code

```d
import std.traits;

enum Runnable;

struct SubSystem
{
void run();
}

struct Manager
{
@Runnable SubSystem subsystem;

void run()
{
static foreach(system; getSymbolsByUDA!(Manager, 
Runnable))

{
system.run();
}
}
}

void main()
{
Manager m;
m.run();
}

```

Result:

```
onlineapp.d(16): Error: value of `this` is not known at compile 
time

```

This seems to me to be the logical way to write this code. What 
am I missing?




Re: Using getSymbolsByUDA in a static foreach loop

2022-01-19 Thread Adam D Ruppe via Digitalmars-d-learn
On Wednesday, 19 January 2022 at 20:46:17 UTC, Jack Stouffer 
wrote:
static foreach(system; getSymbolsByUDA!(Manager, 
Runnable))

{
system.run();
onlineapp.d(16): Error: value of `this` is not known at compile 
time


The getSymbols returns aliases, meaning you hit what I wrote 
about a few days ago:


http://dpldocs.info/this-week-in-d/Blog.Posted_2022_01_10.html#tip-of-the-week

The `this` is a runtime value and all the other `static` things 
work on compile time info.


So you want to `__traits(child, system, this).run()` and it 
should work - the traits child will re-attach a this value.


Re: Using getSymbolsByUDA in a static foreach loop

2022-01-19 Thread Jack Stouffer via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 20:53:29 UTC, Adam D Ruppe wrote:
So you want to `__traits(child, system, this).run()` and it 
should work - the traits child will re-attach a this value.


The error is actually coming from trying to use the result of 
getSymbolsByUDA in the right part of the `static foreach`, not 
the call to the `run` function. Which was odd to me because I 
thought it just returned a `AliasSeq`.


Here's a link to the erroring code with your traits change:

https://run.dlang.io/is/gO84ox


Re: Using getSymbolsByUDA in a static foreach loop

2022-01-19 Thread Adam D Ruppe via Digitalmars-d-learn
On Wednesday, 19 January 2022 at 21:44:57 UTC, Jack Stouffer 
wrote:
The error is actually coming from trying to use the result of 
getSymbolsByUDA in the right part of the `static foreach`


huh..

I never use most of std.traits, they just complicate things. Bleh 
idk, I wouldn't bother with it and loop through the __traits 
instead.




Re: Using getSymbolsByUDA in a static foreach loop

2022-01-19 Thread Jack Stouffer via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 21:49:12 UTC, Adam D Ruppe wrote:
I never use most of std.traits, they just complicate things. 
Bleh idk, I wouldn't bother with it and loop through the 
__traits instead.


Unless I'm missing something obvious this has to be a DMD bug, 
because this prints nothing:


```d
import std.traits;
import std.stdio;

enum Runnable;

struct SubSystem
{
void run()
{
writeln("SubSystem ran");
}
}

struct Manager
{
@Runnable SubSystem subsystem;

void run()
{
static foreach(member; __traits(allMembers, Manager))
{
static foreach (attribute; 
__traits(getAttributes, member))

{
static if (attribute == Runnable)
{
__traits(child, Manager, member).run();
}
}
}
}
}

void main()
{
Manager m;
m.run();
}
```

The `__traits(getAttributes, member)` call always returns an 
empty tuple. Calling `__traits(getAttributes, Manager.subsystem)` 
manually works as expected.


Re: Using getSymbolsByUDA in a static foreach loop

2022-01-19 Thread Adam Ruppe via Digitalmars-d-learn

On Thursday, 20 January 2022 at 00:55:33 UTC, Jack Stouffer wrote:
static foreach(member; __traits(allMembers, 
Manager))


member here is a string, not the member. I prefer to call it 
memberName.


Then you __traits(getMember, Manager, memberName) to actually get 
the alias you can pass to getAttributes.


Re: Using getSymbolsByUDA in a static foreach loop

2022-01-19 Thread Jack Stouffer via Digitalmars-d-learn

On Thursday, 20 January 2022 at 01:14:51 UTC, Adam Ruppe wrote:
On Thursday, 20 January 2022 at 00:55:33 UTC, Jack Stouffer 
wrote:
static foreach(member; __traits(allMembers, 
Manager))


member here is a string, not the member. I prefer to call it 
memberName.


Then you __traits(getMember, Manager, memberName) to actually 
get the alias you can pass to getAttributes.


Thanks, that fixed it. Final working version for anyone who finds 
this thread:


```d
import std.traits;
import std.stdio;

enum Runnable;

struct SubSystem
{
void run()
{
writeln("SubSystem ran");
}
}

struct Manager
{
@Runnable SubSystem subsystem;

void run()
{
static foreach(memberName; __traits(allMembers, Manager))
{
static foreach (attribute; __traits(getAttributes, 
__traits(getMember, Manager, memberName)))

{
static if (is(attribute == Runnable))
{
__traits(getMember, Manager, 
memberName).run();

}
}
}
}
}


void main()
{
Manager m;
m.run();
}
```