How do I generate `setX` methods for all private mutable variables in a class?

Basile B. b2.temp at gmx.com
Mon Jun 5 15:13:43 UTC 2023


On Monday, 5 June 2023 at 13:57:20 UTC, Ki Rill wrote:
> How do I generate `setX` methods for all private mutable 
> variables in my class? Do I need to use `__traits`?
>
> I need this for my 
> [tiny-svg](https://github.com/rillki/tiny-svg) project to 
> generate `setX` methods for all Shapes.
>
> Example:
> ```D
> class Rectangle {
>     private immutable ...;
>     private Color fillColor;
>     private Color strokeColor;
>     private uint strokeWidth;
>
>     this(int x, int y) {...}
>
>     mixin(???);
>
>     // I need this:
>     Rectangle setFillColor(Color color) {...}
>     Rectangle setStrokeColor(Color color) {...}
>     Rectangle setStrokeWidth(uint color) {...}
> }
> ```
>
> Usage:
> ```D
> new Rectangle(10, 10)
>     .setFillColor(Colors.white)
>     .setStrokeColor(Colors.black)
>     .setStrokeWidth(3);
> ```

You need to put an user attribute on the fieldd then to use 
static introspection to generate the setters.

Very basically that works like that

```d
enum Set;
class Color {}

auto generateSetters(T)()
{
     string result;
     import std.traits;
     static foreach (m; __traits(allMembers, T))
     {{
         alias member = __traits(getMember, T, m);
         static if (hasUDA!(member, Set))
             result ~= "void set" ~ m ~  "(" ~ 
typeof(member).stringof ~ "){}\n";
     }}
     return result;
}

class Rectangle {
     @Set private Color fillColor;
     @Set private Color strokeColor;
     @Set private uint strokeWidth;

     mixin(generateSetters!(Rectangle)());
}

void main()
{
     with (new Rectangle) {
         setstrokeWidth(0);
         setstrokeColor(null);
         setfillColor(null);

     }
}
```

although I did not spent time on the setter body... I suppose the 
question was more about the metprogramming technic, and that you 
don't want a pre-mashed solution ;)


More information about the Digitalmars-d-learn mailing list