Property mixin in D example:
/+
' Source : Attr_Mixin.d
' Author : Derek Parnell
' Created : 03.Jul.06
' Ref : http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=39535
' -----------------------------------------------------------------------
' A starting point for better property implementation (done with mixins).
'
' To unittest : dmd attr_mixin.d -unittest -debug=attr_mixin
' To compile : dmd yourcode.d attr_mixin.d
+/
module attr_mixin;
debug( attr_mixin ) private import std.stdio;
debug( attr_mixin ) private import std.string;
// Read and Write Attribute, without a function call.
template AttributeRW(T)
{
private T _xRW;
public T get() { return _xRW; }
public T set(T d) { _xRW = d; return d; }
}
// Read and Write Attribute, with a function call.
template AttributeRW(T, alias F)
{
private T _xRWF;
public T get() { return F(_xRWF, true); }
public T set(T d) { _xRWF = F(d, false); return F(_xRWF, true); }
}
// Read Only Attribute, without a function call.
template AttributeRO(T)
{
private T _xRO;
public T get() { return _xRO; }
}
// Read Only Attribute, with a function call.
template AttributeRO(T, alias F)
{
private T _xROF;
public T get() { return F(_xROF, true); }
}
// Write Only Attribute, without a function call.
template AttributeWO(T)
{
private T _xWO;
public T set(T d) { _xWO = d; return _xWO; }
}
// Write Only Attribute, with a function call.
template AttributeWO(T, alias F)
{
private T _xWOF;
public T set(T d) { _xWOF = F(d, false); return F(_xWOF, true); }
}
debug( attr_mixin )
{
int main()
{
writefln("attr_mixin unittest done!"c);
return 0;
}
}
// Derek Parnell's example with a few minor changes:
unittest
{
class Car
{
mixin attr_mixin.AttributeRW!(int, QA_Colour) Colour;
mixin attr_mixin.AttributeRW!(real) Speed;
mixin attr_mixin.AttributeRO!(real) Torque;
mixin attr_mixin.AttributeWO!(real, QA_Accel) Accel;
mixin attr_mixin.AttributeRO!(char[]) Name;
this(in char[] sCarName)
{
Name._xRO = sCarName;
}
// Set torque on acceleration
private real QA_Accel(real v, bool act)
{
if (act == false)
Torque._xRO = v * 17 / 3;
return v;
}
// Validate Colour
private int QA_Colour(int v, bool act)
{
if (act == false)
if (v >= 0 && v < 256)
Colour._xRWF = v;
else
throw new Error("Bad colour value."c);
return v;
}
}
auto oCar = new Car("Furary"c);
oCar.Colour.set = 4;
oCar.Speed.set = 6.4455;
oCar.Accel.set = 1.2;
writefln("%s ...\n Colour %s, Speed %s, and Torque %s"c,
oCar.Name.get,
oCar.Colour.get,
oCar.Speed.get,
oCar.Torque.get
);
assert(oCar.Name.get == "Furary"c);
assert(oCar.Colour.get == 4);
assert(oCar.Speed.get == 6.4455);
assert(toString(oCar.Torque.get) == "6.8"c);
}
C:\dmd>dmd attr_mixin.d -unittest -debug=attr_mixin
C:\dmd\bin\..\..\dm\bin\link.exe attr_mixin,,,user32+kernel32/noi;
C:\dmd>attr_mixin
Furary ...
Colour 4, Speed 6.4455, and Torque 6.8
attr_mixin unittest done!
C:\dmd>