www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - UFCS & overloaded property getters/setters

reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
I'm not sure if this is a bug, or an anti-pattern, or what, but I ran
into this issue yesterday:

	class Base {
		int propImpl;
		final  property int prop() { return propImpl; }
		 property void prop(int newVal) { propImpl = newVal; }

		void someMethod() {
			auto x = prop; // OK, calls Base.prop()
			prop = x; // OK, calls Base.prop(int)
		}
	}

	class Derived : Base {
		override  property void prop(int newVal) {
			super.prop(newVal);
			doSomethingElse(newVal);
		}

		void someOtherMethod() {
			auto x = prop; // NG - compile error ***
			auto y = super.prop; // OK, calls Base.prop()
			prop = x; // OK, calls Derived.prop()
		}
	}

Basically, once the derived class overrides the property setter, the
(un-overridden) base class getter somehow becomes shadowed as well, and
references to .prop will cause a compile error saying that Derived.prop
can't be called without parameters.

So, what's going on here? Should this code be accepted? Is this a
compiler / language bug? A deliberate  property limitation? Or just more
evidence  property should be taken out the back and shot?


T

-- 
This sentence is false.
Jun 13 2014
next sibling parent "Kapps" <opantm2+spam gmail.com> writes:
Odd, I thought you weren't able to override only a single 
overload of a property? I might be imagining things, but I recall 
at least previously that you had to override all getters/setters 
if you wanted to override any for a property.

Personally I think D made a significant mistake in the way 
properties are handled, with treating them as multiple methods 
tenuously tied together with sticking  property on (hopefully) 
all of them. I'd much rather it were a single property with 
getters/setters inside, similar to the way C# does it. Ideally 
something like:

/// Documentation
 property int foo()  safe pure nothrow {
     get() const { return _bar.foo; }
     set(int val) { _bar.foo = val; }
}

As opposed to

/// Documentation
 property int foo() const  safe pure nothrow {
     return _bar.foo;
}

/// ditto
 property void foo(int val)  safe pure nothrow {
     _bar.foo = val;
}

Then you would actually have to override all or nothing, it would 
be treated as a single property not as multiple method overloads, 
etc.
Jun 13 2014
prev sibling parent Shammah Chancellor <shammah.chancellor gmail.com> writes:
On 2014-06-13 16:39:04 +0000, H. S. Teoh via Digitalmars-d said:

 
 Basically, once the derived class overrides the property setter, the
 (un-overridden) base class getter somehow becomes shadowed as well, and
 references to .prop will cause a compile error saying that Derived.prop
 can't be called without parameters.
 
 So, what's going on here? Should this code be accepted? Is this a
 compiler / language bug? A deliberate  property limitation? Or just more
 evidence  property should be taken out the back and shot?
 
 
 T

I had absolutely no problems with the following code. Note where and how the alias for prop is located. import std.stdio; class Base { int propImpl; final property int prop() { writefln("hihihi!"); return propImpl; } property void prop(int newVal) { propImpl = newVal; } void someMethod() { auto x = prop; // OK, calls Base.prop() prop = x; // OK, calls Base.prop(int) } } class Derived : Base { alias prop = super.prop; override property void prop(int newVal) { super.prop(newVal); writefln("Hello!"); } void someOtherMethod() { auto x = prop; // NG - compile error *** auto y = super.prop; // OK, calls Base.prop() prop = x; // OK, calls Derived.prop() } } void main() { auto foo = new Derived(); foo.someOtherMethod(); }
Jun 13 2014