Robert Jacques Wrote: > On Thu, 05 Feb 2009 06:55:46 -0500, Alex Burton <alex...@mac.com> wrote: > > > Hi, > > > > I just found a bug that comes out of the property syntax. > > > > The property syntax is great in that it allows a smooth transition from > > simple code dealing with public member variables to the use of > > interfaces without needing to update the client code. > > i.e. A.bob = 1 can stay as A.bob = 1 when bob changes from being an int > > to being void A::bob(int i) > > instead of changing to A.bob(1). > > > > But this can introduce the bug I show below. > > > > Proposal : > > If the temporary returned by the property syntax getter function is > > modified, then the corresponding setter function needs to be called with > > the temporary as argument. > > > > struct A > > { > > int i; > > int j; > > }; > > > > class B > > { > > A mA; > > public: > > A a() { return mA; } > > void a(A a) { mA = a; } > > }; > > > > > > int main() > > { > > B b; > > b.a.j = 10; // error b.a is a temporary. > > } > > This isn't a bug, it's a feature. What you wanted to use were ref returns > (see http://www.digitalmars.com/d/2.0/function.html ) > ref A a() { return mA; }
Using ref A a() { return mA; } requires us to have a member variable mA ( which is actually there in the example). One of the reasons for using the setter and getter functions instead of the raw member variable is that there is not actually a member variable. For example: A a() { Dataset ds = mDatabase.Execute("SELECT A,B FROM TABLE"); return A(ds[0][0],ds[0][1]); } void a(A a) { mDatabase.Execute(format("INSERT %d,%d INTO TABLE;",a.i,a.j)); } The only way I can see to handle this correctly is to use my proposal above. This could be a really valuable feature in D if correctly implemented. Being able to transparently change from a member variable in a struct to getters and setters on a struct to getters and setters on a class and in reverse order is really powerful and allows code to evolve in a much more fluid way. Alex