Puzzled

Timon Gehr timon.gehr at gmx.ch
Tue Dec 12 21:48:59 UTC 2023


On 12/12/23 20:02, Don Allen wrote:
> Since ceasing my use of D out of concern for the direction and health of 
> the project, I've nonetheless been following these forums and have seen 
> what I consider to be sincere efforts to improve things.
> 
> So I've started doing a bit of D work again and ran into this:
> 
> ````
> import std.stdio;
> 
> struct Foo {
>      int bar;
>      int baz;
> }
> ...

This defines three symbols:

Foo
Foo.bar
Foo.baz

There is however no `bar` and no `baz` at module scope.


> void bletch(alias field)(Foo s, int x) {
>      s.field = x;
>      writeln("%d", s.field);
> }
> ...

This attempts to access `s.field`, but `field` is not a member of `Foo`.


> int main(string[] args)
> {
>      Foo s;
>      bletch!bar(s);
>      bletch!baz(s);
>      return 0;
> }
> ````
> ...

This find neither `bar` nor `baz`, because those are nested in `Foo`. 
There are symbols `Foo.bar` and `Foo.baz`, but not `bar` and `baz`.


The idiomatic way to achieve what you want is this:

```d
import std.stdio;

struct Foo{
     int bar;
     int baz;
}

void bletch(string field)(Foo s, int x){
     __traits(getMember, s, field) = x;
     writeln(__traits(getMember, s, field));
}

void main(){
     Foo s;
     bletch!"bar"(s, 1);
     bletch!"baz"(s, 2);
}
```

Arguably this is not very nice, but it does the job.

You can pass `Foo.bar` and `Foo.baz` as aliases, but I think currently 
there is no good way to access a field of an object based on an alias to 
the field symbol. (Other than `__traits(getMember, self, 
__traits(identifier, field))`, but that bypasses all the typechecking 
you might get anyway.)




More information about the Digitalmars-d mailing list