digitalmars.D.learn - class invariants and property declarations
- Michael Engelhardt (42/42) Feb 16 2011 Hi,
- Dmitry Olshansky (25/67) Feb 16 2011 Welcome on board :)
- Jesse Phillips (2/7) Feb 16 2011 Why shouldn't it be allowed? While it provides no benefit it does docume...
- Dmitry Olshansky (8/15) Feb 16 2011 Well, it does not affect the code in any meaningful way. Also it's not
- Jonathan M Davis (8/15) Feb 16 2011 Except that @property is for _functions_. You mark a function with @prop...
- Jesse Phillips (9/16) Feb 17 2011 class Foo {
- Jonathan M Davis (10/31) Feb 17 2011 Except that @property on a variable does _nothing_. It's totally inappro...
- Steven Schveighoffer (6/15) Feb 16 2011 Regardless of this, you should be aware that an invariant is not called ...
Hi, I just have started diving in D. Exploring the contract feature I stumbled upon the fact that a class invariant does not apply to properties: import std.stdio; void main(string[] args) { Time t = new Time(); t.hours = 24; // works; why? writeln("t.hours is ", t.hours); t.add(1); // triggers an assertion failure as expected writeln("t.hours is ", t.hours); } class Time { invariant() { assert( 0 <= hours && hours < 13); } property int hours; public void add(int hours) { this.hours += hours; } } compiled using Digital Mars DMD (2.051 on Ubuntu 10.10) is given the following result: t.hours is 24 core.exception.AssertError invarprop(13): Assertion failure ---------------- ./InVariantProperty() [0x8057ade] ./InVariantProperty() [0x804f7e6] ./InVariantProperty() [0x804cba3] ./InVariantProperty() [0x8049856] ./InVariantProperty() [0x804fa86] ./InVariantProperty() [0x8049869] ./InVariantProperty() [0x8049813] ./InVariantProperty() [0x804f9f2] ./InVariantProperty() [0x804f94c] ./InVariantProperty() [0x804fa36] ./InVariantProperty() [0x804f94c] ./InVariantProperty() [0x804f8f4] /lib/libc.so.6(__libc_start_main+0xe7) [0xa5cce7] ./InVariantProperty() [0x8049721] Should not a class invariant apply to properties, too? Kind regards Michael
Feb 16 2011
On 16.02.2011 11:03, Michael Engelhardt wrote:Hi, I just have started diving in D. Exploring the contract feature I stumbled upon the fact that a class invariant does not apply to properties:Welcome on board :) Invariant gets called on every public method call (at begin & end if I'm not mistaken). Now to properties, this is actually shouldn't be allowed: property int hours; property is a annotation applied to functions (getter/setter), to allow calling it with omitted () and a natural assign syntax like this: class Time { private: int _hours; public: //... property int hours() { return _hours; } property void hours(int newHours) { _hours = newHours; } } auto t = new Time(); t.hours = 5; // calls void hours(5) assert(t.hours == 5); //calls int hours() Now given that setter and getter are public methods they'd got the invariant called.import std.stdio; void main(string[] args) { Time t = new Time(); t.hours = 24; // works; why? writeln("t.hours is ", t.hours); t.add(1); // triggers an assertion failure as expected writeln("t.hours is ", t.hours); } class Time { invariant() { assert( 0<= hours&& hours< 13); } property int hours; public void add(int hours) { this.hours += hours; } } compiled using Digital Mars DMD (2.051 on Ubuntu 10.10) is given the following result: t.hours is 24 core.exception.AssertError invarprop(13): Assertion failure ---------------- ./InVariantProperty() [0x8057ade] ./InVariantProperty() [0x804f7e6] ./InVariantProperty() [0x804cba3] ./InVariantProperty() [0x8049856] ./InVariantProperty() [0x804fa86] ./InVariantProperty() [0x8049869] ./InVariantProperty() [0x8049813] ./InVariantProperty() [0x804f9f2] ./InVariantProperty() [0x804f94c] ./InVariantProperty() [0x804fa36] ./InVariantProperty() [0x804f94c] ./InVariantProperty() [0x804f8f4] /lib/libc.so.6(__libc_start_main+0xe7) [0xa5cce7] ./InVariantProperty() [0x8049721] Should not a class invariant apply to properties, too? Kind regards Michael-- Dmitry Olshansky
Feb 16 2011
Dmitry Olshansky Wrote:Now to properties, this is actually shouldn't be allowed: property int hours; property is a annotation applied to functions (getter/setter), to allow calling it with omitted () and a natural assign syntax like this:Why shouldn't it be allowed? While it provides no benefit it does document that it is a property.
Feb 16 2011
On 16.02.2011 20:47, Jesse Phillips wrote:Dmitry Olshansky Wrote:Well, it does not affect the code in any meaningful way. Also it's not the property per see it's data member, you can even take it's address. To me such 'features' that silently do nothing should be an error. As to document anything then the comment does it and without the phantom semantic load. -- Dmitry OlshanskyNow to properties, this is actually shouldn't be allowed: property int hours; property is a annotation applied to functions (getter/setter), to allow calling it with omitted () and a natural assign syntax like this:Why shouldn't it be allowed? While it provides no benefit it does document that it is a property.
Feb 16 2011
On Wednesday, February 16, 2011 09:47:32 Jesse Phillips wrote:Dmitry Olshansky Wrote:calling it with omitted () and a natural assign syntax like this:Now to properties, this is actually shouldn't be allowed: property int hours; property is a annotation applied to functions (getter/setter), to allowWhy shouldn't it be allowed? While it provides no benefit it does document that it is a property.Except that property is for _functions_. You mark a function with property so that it _acts_ like a variable. property on a variable is _meaningless_. It would be like marking a variable nothrow. It makes no sense. Neither should be legal. The fact that a member variable is public makes it a property. property on a member variable makes no sense. - Jonathan M Davis
Feb 16 2011
Jonathan M Davis Wrote:Except that property is for _functions_. You mark a function with property so that it _acts_ like a variable. property on a variable is _meaningless_. It would be like marking a variable nothrow. It makes no sense. Neither should be legal. The fact that a member variable is public makes it a property. property on a member variable makes no sense. - Jonathan M Davisclass Foo { property { int min; int hour() { return _hour;} ... } } I agree that useless markings should usually be disallowed, but for me there is visual cues that property provides and if I'm declaring a number of public fields/functions I'd want the present them in a similar manner.
Feb 17 2011
On Thursday, February 17, 2011 10:39:20 Jesse Phillips wrote:Jonathan M Davis Wrote:Except that property on a variable does _nothing_. It's totally inappropriate. I really think that it should be a bug. It wouldn't make any sense to mark a variable as nothrow would it? A public member variable is both a property and nothrow by its very nature. Now, sadly enough, if you replace property with nothrow in the code above (and remove the ... and make sure that there's actually an _hour variable), it compiles just fine, so the compiler is being ridiculously lax about attributes that aren't valid. - Jonathan M DavisExcept that property is for _functions_. You mark a function with property so that it _acts_ like a variable. property on a variable is _meaningless_. It would be like marking a variable nothrow. It makes no sense. Neither should be legal. The fact that a member variable is public makes it a property. property on a member variable makes no sense. - Jonathan M Davisclass Foo { property { int min; int hour() { return _hour;} ... } } I agree that useless markings should usually be disallowed, but for me there is visual cues that property provides and if I'm declaring a number of public fields/functions I'd want the present them in a similar manner.
Feb 17 2011
On Wed, 16 Feb 2011 12:47:32 -0500, Jesse Phillips <jessekphillips+D gmail.com> wrote:Dmitry Olshansky Wrote:Regardless of this, you should be aware that an invariant is not called when a public field is changed/accessed, whether it's marked with property or not. Only member functions invoke the invariant. -SteveNow to properties, this is actually shouldn't be allowed: property int hours; property is a annotation applied to functions (getter/setter), to allow calling it with omitted () and a natural assign syntax like this:Why shouldn't it be allowed? While it provides no benefit it does document that it is a property.
Feb 16 2011