digitalmars.D - Using unary expressions with property functions
- Andrej Mitrovic (71/71) Dec 13 2010 So I was a bit surprised today to find out that this sample C# code work...
- Jonathan M Davis (16/109) Dec 13 2010 I would think that it would be doable if something ++lib.NumCopies were ...
- Robert Jacques (4/126) Dec 14 2010 I know this concept has been extensively discussed before, i.e. the
class LibraryItem { private int _numCopies; // Property public int NumCopies { get { return _numCopies; } set { _numCopies = value; } } public void BorrowItem(string name) { NumCopies--; } } Apparently you can use the -- and ++ unary ops on property functions, which might be convenient, I guess. But this won't work in D: class LibraryItem { private int _numCopies; property int NumCopies() { return _numCopies; } property void NumCopies(int value) { _numCopies = value; } public void BorrowItem(string name) { NumCopies--; } } void main() { } I get this back: Error: this.NumCopies() is not an lvalue So D tries to call the getter method "int NumCopies()" and apply -- on it. One way around this is to make the getter method return by reference: import std.stdio; class LibraryItem { private int _numCopies; property ref int NumCopies() { return _numCopies; } property void NumCopies(int value) { _numCopies = value; } public void BorrowItem(string name) { NumCopies--; writeln(NumCopies); // writes -1 after the call } } void main() { auto lib = new LibraryItem(); lib.BorrowItem("TDPL"); } So this works. But now the getter method acts both as a getter and a setter, which contradicts the idea of having separate get/set methods, don't you agree? for the -- op like in the last D example, or does it rewrite the whole operation as "NumCopies(-1)"? Maybe we can have a functionality like that in D without having to change the getter method to return a reference.. What do you think?
Dec 13 2010
On Monday, December 13, 2010 11:10:55 Andrej Mitrovic wrote:class LibraryItem { private int _numCopies; // Property public int NumCopies { get { return _numCopies; } set { _numCopies = value; } } public void BorrowItem(string name) { NumCopies--; } } Apparently you can use the -- and ++ unary ops on property functions, which might be convenient, I guess. But this won't work in D: class LibraryItem { private int _numCopies; property int NumCopies() { return _numCopies; } property void NumCopies(int value) { _numCopies = value; } public void BorrowItem(string name) { NumCopies--; } } void main() { } I get this back: Error: this.NumCopies() is not an lvalue So D tries to call the getter method "int NumCopies()" and apply -- on it. One way around this is to make the getter method return by reference: import std.stdio; class LibraryItem { private int _numCopies; property ref int NumCopies() { return _numCopies; } property void NumCopies(int value) { _numCopies = value; } public void BorrowItem(string name) { NumCopies--; writeln(NumCopies); // writes -1 after the call } } void main() { auto lib = new LibraryItem(); lib.BorrowItem("TDPL"); } So this works. But now the getter method acts both as a getter and a setter, which contradicts the idea of having separate get/set methods, don't you agree? reference for the -- op like in the last D example, or does it rewrite the whole operation as "NumCopies(-1)"? Maybe we can have a functionality like that in D without having to change the getter method to return a reference.. What do you think?I would think that it would be doable if something ++lib.NumCopies were lowered to lib.NumCopies(++lib.NumCopies()). If it were post-increment, it would then probably turn it into something more like this: auto toInc = lib.NumCopies(); auto temp = toInc; lib.NumCopies(++toInc); Of course, given that you could use pre and post-increment in the middle of an expression, that could get quite a bit more complicated, and a simple lowering could be rather difficult, but the basic idea should still hold. I don't see why it couldn't be done other than that figuring out the exact way to lower it in order to deal with the fact that it could be in the middle of an expression could be a bit entertaining. I say open an enhancement request for it. Perhaps someone else can point out why it would be a bad idea, but on the surface, it seems quite doable. - Jonathan M Davis
Dec 13 2010
On Mon, 13 Dec 2010 14:29:34 -0500, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Monday, December 13, 2010 11:10:55 Andrej Mitrovic wrote:I know this concept has been extensively discussed before, i.e. the problem of a.b.c.d = 1, when b, c or d happen to be a method/property.works: class LibraryItem { private int _numCopies; // Property public int NumCopies { get { return _numCopies; } set { _numCopies = value; } } public void BorrowItem(string name) { NumCopies--; } } Apparently you can use the -- and ++ unary ops on property functions, which might be convenient, I guess. But this won't work in D: class LibraryItem { private int _numCopies; property int NumCopies() { return _numCopies; } property void NumCopies(int value) { _numCopies = value; } public void BorrowItem(string name) { NumCopies--; } } void main() { } I get this back: Error: this.NumCopies() is not an lvalue So D tries to call the getter method "int NumCopies()" and apply -- on it. One way around this is to make the getter method return by reference: import std.stdio; class LibraryItem { private int _numCopies; property ref int NumCopies() { return _numCopies; } property void NumCopies(int value) { _numCopies = value; } public void BorrowItem(string name) { NumCopies--; writeln(NumCopies); // writes -1 after the call } } void main() { auto lib = new LibraryItem(); lib.BorrowItem("TDPL"); } So this works. But now the getter method acts both as a getter and a setter, which contradicts the idea of having separate get/set methods, don't you agree? reference for the -- op like in the last D example, or does it rewrite the whole operation as "NumCopies(-1)"? Maybe we can have a functionality like that in D without having to change the getter method to return a reference.. What do you think?I would think that it would be doable if something ++lib.NumCopies were lowered to lib.NumCopies(++lib.NumCopies()). If it were post-increment, it would then probably turn it into something more like this: auto toInc = lib.NumCopies(); auto temp = toInc; lib.NumCopies(++toInc); Of course, given that you could use pre and post-increment in the middle of an expression, that could get quite a bit more complicated, and a simple lowering could be rather difficult, but the basic idea should still hold. I don't see why it couldn't be done other than that figuring out the exact way to lower it in order to deal with the fact that it could be in the middle of an expression could be a bit entertaining. I say open an enhancement request for it. Perhaps someone else can point out why it would be a bad idea, but on the surface, it seems quite doable. - Jonathan M Davis
Dec 14 2010