Search code examples
d

Is there a d-lang equivalent of Ruby's attr_accessor


In Ruby I can easily set read/write properties on a class like this:

class Bar
  attr_accessor :foo, :bizz, :buzz
end

This would be the same as

class Bar
  def foo
    @foo
  end

  def foo=(foo)
    @foo = foo
  end

  def bizz
    @foo
  end

  def bizz=(bizz)
    @bizz = bizz
  end

  def buzz
    @buzz
  end

  def buzz=(buzz)
    @buzz = buzz
  end
end

The same code is D is very verbose, and I find myself repeating things all over the place:

class Bar {
  private {
    string _foo, _bizz, _buzz;
  }

  @property {
    string foo()  { return _foo;  }
    string bizz() { return _bizz; }
    string buzz() { return _buzz; }

    void foo(string foo)   { _foo = foo;   }
    void bizz(string bizz) { _bizz = bizz; }
    void buzz(string buzz) { _buzz = buzz; }
  }
}

Is there a short hand way to do this?


Solution

  • yes:

    public string foo;
    

    Trivial property accessors are a waste of time IMO. Ruby forces you to do them but D doesn't.

    If you want them anyway, a mixin template can do the job:

    mixin template attr_accessor(Type, string name) {
        static string codeGenerationHelper() {
            string code;
            // the variable
            code ~= "private Type _" ~ name ~ ";";
    
            // the getter
            code ~= "public @property Type " ~ name ~ "() { return _" ~ name ~ "; }";
    
            // the setter
            code ~= "public @property Type " ~ name ~ "(Type a) { return _" ~ name ~ " = a; }";
    
            return code;
        }
    
        mixin(codeGenerationHelper());
    }
    
    // here's how to use it
    class Foo {
        mixin attr_accessor!(string, "foo");
    }
    
    void main() {
        auto foo = new Foo();
        foo.foo = "test";
    }