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

2023-06-06 Thread Ki Rill via Digitalmars-d-learn

On Monday, 5 June 2023 at 18:54:30 UTC, cc wrote:

[...]


Is there a way to check for mutability as well? I have both 
immutable and mutable fields. I would like to generate setters 
for mutable fields only.





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

2023-06-06 Thread Ali Çehreli via Digitalmars-d-learn

On 6/6/23 09:13, Basile B. wrote:

> yeah I know that opDispatch is disliked because it is tried in a SFINAE
> fashion, as citicized by Adam. But on the other side it's the best 
opover.


I like how it helped in my current project:

  user.someShellCommand("-foo", "-bar");

opDispatch makes a command string, passes it to executeShell, takes care 
of the return code and dumps its output if there was an error.


Ali



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

2023-06-06 Thread Basile B. via Digitalmars-d-learn
On Tuesday, 6 June 2023 at 14:23:59 UTC, Steven Schveighoffer 
wrote:

On 6/5/23 11:33 AM, Basile B. wrote:

[...]


Ugh, don't do it that way. Always give opDispatch a template 
constraint or it will suck to use.


Also, given the problem constraints, you can build the method 
automatically using the string.


```d
auto opDispatch(string member, T)(auto ref T t) 
if(member.startsWith("set"))

{
   mixin(toLower(m[3]), m[4 .. $], " = t;");
}
```

-Steve


yeah I know that opDispatch is disliked because it is tried in a 
SFINAE fashion, as citicized by Adam. But on the other side it's 
the best opover.


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

2023-06-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/5/23 11:33 AM, Basile B. wrote:

On Monday, 5 June 2023 at 15:13:43 UTC, Basile B. wrote:

On Monday, 5 June 2023 at 13:57:20 UTC, Ki Rill wrote:

How do I generate `setX` methods for all private mutable


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 ;)


By the way...an other solution is to use 
[opDispatch](https://dlang.org/spec/operatoroverloading.html#dispatch):


```d
class Color {}

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

     auto opDispatch(string member, T)(auto ref T t)
     {
  static if (member == "setStrokeWidth") {}
     else static if (member == "setStrokeColor") {}
     else static if (member == "setFillColor") {}
     else static assert(0, "cannot set " ~ member);
     return this;
     }
}

void main()
{
     (new Rectangle)
     .setStrokeWidth(0)
     .setStrokeColor(null)
     .setFillColor(null);
}
```


Ugh, don't do it that way. Always give opDispatch a template constraint 
or it will suck to use.


Also, given the problem constraints, you can build the method 
automatically using the string.


```d
auto opDispatch(string member, T)(auto ref T t) if(member.startsWith("set"))
{
   mixin(toLower(m[3]), m[4 .. $], " = t;");
}
```

-Steve


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

2023-06-06 Thread Basile B. via Digitalmars-d-learn

On Monday, 5 June 2023 at 15:28:34 UTC, Paul Backus wrote:

Is there a reason you can't just make these fields `public`?


My bet is that OP actually wants to generate something like

```d
void setStrokeWidth(uint value)
{
if (value = strokeWidth) return;
strokeWidth = value;
redraw();
// or maybe...
// needRedraw = true;
}
```

that's a common pattern in 2D graphic libraries.


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

2023-06-06 Thread Basile B. via Digitalmars-d-learn

On Monday, 5 June 2023 at 15:28:34 UTC, Paul Backus wrote:

Is there a reason you can't just make these fields `public`?


My bet is that OP actually wants to generate something like

```d
void setStrokeWidth(uint value)
{
if (value = strokeWidth) return;
strokeWidth = value;
redraw();
// or maybe...
// needRedraw = true;
}
```

that's a common pattern in 2D graphics libraries


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

2023-06-05 Thread Ki Rill via Digitalmars-d-learn

On Monday, 5 June 2023 at 18:54:30 UTC, cc wrote:

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`?


```d
mixin template GenerateSetters() {
	static foreach (idx, field; typeof(this).tupleof) static if 
(__traits(getVisibility,field) == "private") {

mixin(q{
void %SETTER(typeof(this.tupleof[idx]) _) {
%NAME = _;
}
}
.replace("%NAME", field.stringof)
			.replace("%SETTER", "set"~toUpper(field.stringof[0..1]) ~ 
field.stringof[1..$])

);
}
}
class Rectangle {
private Color fillColor;
private Color strokeColor;
private uint strokeWidth;

this(int x, int y) {}

mixin GenerateSetters;
}

void main() {
auto rect = new Rectangle(0, 0);
rect.setStrokeWidth(4);
assert(rect.strokeWidth == 4);
}
```


Thank you! That is exactly what I needed. Although another 
solution provided by Basile B. using attributes opens a door for 
other posibilities...


I don't usually use metaprogramming or code generation much, this 
is an eye-opening experience.


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

2023-06-05 Thread cc via Digitalmars-d-learn

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`?


```d
mixin template GenerateSetters() {
	static foreach (idx, field; typeof(this).tupleof) static if 
(__traits(getVisibility,field) == "private") {

mixin(q{
void %SETTER(typeof(this.tupleof[idx]) _) {
%NAME = _;
}
}
.replace("%NAME", field.stringof)
			.replace("%SETTER", "set"~toUpper(field.stringof[0..1]) ~ 
field.stringof[1..$])

);
}
}
class Rectangle {
private Color fillColor;
private Color strokeColor;
private uint strokeWidth;

this(int x, int y) {}

mixin GenerateSetters;
}

void main() {
auto rect = new Rectangle(0, 0);
rect.setStrokeWidth(4);
assert(rect.strokeWidth == 4);
}
```


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

2023-06-05 Thread Basile B. via Digitalmars-d-learn

On Monday, 5 June 2023 at 15:13:43 UTC, Basile B. wrote:

On Monday, 5 June 2023 at 13:57:20 UTC, Ki Rill wrote:

How do I generate `setX` methods for all private mutable


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 ;)


By the way...an other solution is to use 
[opDispatch](https://dlang.org/spec/operatoroverloading.html#dispatch):


```d
class Color {}

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

auto opDispatch(string member, T)(auto ref T t)
{
 static if (member == "setStrokeWidth") {}
else static if (member == "setStrokeColor") {}
else static if (member == "setFillColor") {}
else static assert(0, "cannot set " ~ member);
return this;
}
}

void main()
{
(new Rectangle)
.setStrokeWidth(0)
.setStrokeColor(null)
.setFillColor(null);
}
```

Sure the first solution takes advantage of D features but to 
generate code that finally looks like C# or Delphi (`Set`, `Get`; 
`property`, etc.)


On top of that I tend to prefer the later solution because 
self-introspection based on `__traits` has corner issues, 
especially when typecons-like structures are used for the members 
(e.g sumtype, nullable, etc.).


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

2023-06-05 Thread Paul Backus via Digitalmars-d-learn

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) {...}
}
```


Is there a reason you can't just make these fields `public`?

D supports property accessors, so you can always go back and make 
them `private` later on if it turns out you need to. For example:


```d
// Before
class MyClass1
{
public int data;
}

void example1(MyClass1 c)
{
c.data = 123; // set
int n = c.data; // get
}

// After
class MyClass2
{
private int data_;
int data() { return data; }
void data(int value) { data = value; }
}

void example2(MyClass2 c)
{
// Usage is exactly the same
c.data = 123; // set
int n = c.data; // get
}
```


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

2023-06-05 Thread Basile B. via Digitalmars-d-learn

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 ;)


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

2023-06-05 Thread Ki Rill via Digitalmars-d-learn
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);
```