On Saturday, 30 May 2020 at 22:21:14 UTC, Paul Backus wrote:
enum f(string x) = "_" ~ x;
int main() {
mixin("int ", f!"x", " = 3;");
return _x;
}
This uses a templated [1] manifest constant [2] to generate the
variable name at compile time, and a mixin statement [3] to
insert the definition of `_x` into the program.
[1] https://dlang.org/spec/template.html#variable-template
[2] https://dlang.org/spec/enum.html#manifest_constants
[3] https://dlang.org/spec/statement.html#mixin-statement
Thank you all for the reply.
I hate to write boilerplate code:
class Point {
private int _x;
public int x() {return _x;}
public Point x(int v) {_x=v; return this;}
...
// ... y, z
}
this is what I've got:
$ cat b.d
--------------------------------------------------------------------------------
// dmd -unittest -vcg-ast -c b.d
import std.format;
enum RW(string T, string name) =
format(q{
private %1$s _%2$s;
public %1$s %2$s() {return _%2$s;}
public auto %2$s(%1$s v) {_%2$s = v; return this;}
}, T, name);
class Point {
mixin(RW!("int", "x"));
mixin(RW!("double", "y"));
mixin(RW!("string", "z"));
}
$ dmd -unittest -vcg-ast -c b.d
$ head -n 24 b.d.cg
import object;
import std.format;
enum RW(string T, string name) = format("\x0a private %1$s
_%2$s;\x0a public %1$s %2$s() {return _%2$s;}\x0a
public auto %2$s(%1$s v) {_%2$s = v; return this;}\x0a ", T,
name);
class Point : Object
{
mixin(RW!("int", "x")
{
enum string RW = ['\x0a', ' ', ' ', ' ', ' ',
'p', 'r', 'i', 'v', 'a', 't', 'e', ' ', 'i', 'n', 't', ' ', '_',
'x', ';', '\x0a', ' ', ' ', ' ', ' ', 'p', 'u', 'b', 'l', 'i',
'c', ' ', ' ', 'i', 'n', 't', ' ', ' ', 'x', '(', ')', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', '{', 'r', 'e', 't', 'u', 'r', 'n',
' ', '_', 'x', ';', '}', '\x0a', ' ', ' ', ' ', ' ', 'p', 'u',
'b', 'l', 'i', 'c', ' ', ' ', 'a', 'u', 't', 'o', ' ', ' ', 'x',
'(', 'i', 'n', 't', ' ', 'v', ')', ' ', ' ', '{', '_', 'x', ' ',
'=', ' ', 'v', ';', ' ', ' ', 'r', 'e', 't', 'u', 'r', 'n', ' ',
't', 'h', 'i', 's', ';', '}', '\x0a', ' ', ' '];
}
);
mixin(RW!("double", "y")
{
enum string RW = ['\x0a', ' ', ' ', ' ', ' ',
'p', 'r', 'i', 'v', 'a', 't', 'e', ' ', 'd', 'o', 'u', 'b', 'l',
'e', ' ', '_', 'y', ';', '\x0a', ' ', ' ', ' ', ' ', 'p', 'u',
'b', 'l', 'i', 'c', ' ', ' ', 'd', 'o', 'u', 'b', 'l', 'e', ' ',
' ', 'y', '(', ')', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '{',
'r', 'e', 't', 'u', 'r', 'n', ' ', '_', 'y', ';', '}', '\x0a', '
', ' ', ' ', ' ', 'p', 'u', 'b', 'l', 'i', 'c', ' ', ' ', 'a',
'u', 't', 'o', ' ', ' ', 'y', '(', 'd', 'o', 'u', 'b', 'l', 'e',
' ', 'v', ')', ' ', ' ', '{', '_', 'y', ' ', '=', ' ', 'v', ';',
' ', ' ', 'r', 'e', 't', 'u', 'r', 'n', ' ', 't', 'h', 'i', 's',
';', '}', '\x0a', ' ', ' '];
}
);
mixin(RW!("string", "z")
{
enum string RW = ['\x0a', ' ', ' ', ' ', ' ',
'p', 'r', 'i', 'v', 'a', 't', 'e', ' ', 's', 't', 'r', 'i', 'n',
'g', ' ', '_', 'z', ';', '\x0a', ' ', ' ', ' ', ' ', 'p', 'u',
'b', 'l', 'i', 'c', ' ', ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
' ', 'z', '(', ')', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '{',
'r', 'e', 't', 'u', 'r', 'n', ' ', '_', 'z', ';', '}', '\x0a', '
', ' ', ' ', ' ', 'p', 'u', 'b', 'l', 'i', 'c', ' ', ' ', 'a',
'u', 't', 'o', ' ', ' ', 'z', '(', 's', 't', 'r', 'i', 'n', 'g',
' ', 'v', ')', ' ', ' ', '{', '_', 'z', ' ', '=', ' ', 'v', ';',
' ', ' ', 'r', 'e', 't', 'u', 'r', 'n', ' ', 't', 'h', 'i', 's',
';', '}', '\x0a', ' ', ' '];
}
);
}
--------------------------------------------------------------------------------
Am I doing the right thing in D? any improvement you'd suggest?
e.g. I don't quite like have to put the type and var name in the
quotes as string:
mixin(RW!("int", "x"));
Is there a better way to achieve this? esp. for the type `int`,
is there any way I don't have to quote it as string?
Thanks.