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.

Reply via email to