www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Member not accessible in delegate body

reply John C <johnch_atms hotmail.com> writes:
If I try to call the protected method of a superclass from inside 
the body of a delegate, the compiler won't allow it.

void layoutTransaction(Control c, void delegate() action) {
   // do stuff
   action();
   // do more stuff
}

class Control {
   protected void onTextChanged() {}
}

class Label : Control {
   protected override void onTextChanged() {
     layoutTransaction(this, {
       super.onTextChanged(); // <--- Error here
       changeSize();
     });
   }
   private void changeSize() {}
}

Output: class Control member onTextChanged is not accessible.

How is it possible that "onTextChanged" isn't accessible but the 
private method "changeSize" *is*?
Sep 23 2016
next sibling parent reply Rene Zwanenburg <renezwanenburg gmail.com> writes:
On Friday, 23 September 2016 at 07:54:15 UTC, John C wrote:
 How is it possible that "onTextChanged" isn't accessible but 
 the private method "changeSize" *is*?
Smells like an oversight. I guess the compiler doesn't see the delegate as a member of a Control subclass, so it can't access protected members. Private works because private in D means module private. Please file an issue. As a workaround you can try to take the address of the method in the closure (untested): void delegate() foo() { auto func = &super.someProtectedFunc; return () => func(); // I think this will work }
Sep 23 2016
parent Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 23 September 2016 at 15:29:43 UTC, Rene Zwanenburg 
wrote:
 On Friday, 23 September 2016 at 07:54:15 UTC, John C wrote:
 How is it possible that "onTextChanged" isn't accessible but 
 the private method "changeSize" *is*?
Smells like an oversight. I guess the compiler doesn't see the delegate as a member of a Control subclass, so it can't access protected members. Private works because private in D means module private. Please file an issue. As a workaround you can try to take the address of the method in the closure (untested): void delegate() foo() { auto func = &super.someProtectedFunc; return () => func(); // I think this will work }
Quoting the document: "protected only applies inside classes (and templates as they can be mixed in) and means that a symbol can only be seen by members of the same module, or by a derived class." So protected also means module visibility.
Sep 23 2016
prev sibling parent reply Martin Nowak <code dawg.eu> writes:
On Friday, 23 September 2016 at 07:54:15 UTC, John C wrote:
 If I try to call the protected method of a superclass from 
 inside the body of a delegate, the compiler won't allow it.

 void layoutTransaction(Control c, void delegate() action) {
   // do stuff
   action();
   // do more stuff
 }

 class Control {
   protected void onTextChanged() {}
 }

 class Label : Control {
   protected override void onTextChanged() {
     layoutTransaction(this, {
       super.onTextChanged(); // <--- Error here
       changeSize();
     });
   }
   private void changeSize() {}
 }

 Output: class Control member onTextChanged is not accessible.

 How is it possible that "onTextChanged" isn't accessible but 
 the private method "changeSize" *is*?
Please file a bug report issues.dlang.org, shouldn't be difficult to fix.
Sep 23 2016
parent John C <johnch_atms hotmail.com> writes:
On Friday, 23 September 2016 at 18:20:24 UTC, Martin Nowak wrote:
 Please file a bug report issues.dlang.org, shouldn't be 
 difficult to fix.
Done: https://issues.dlang.org/show_bug.cgi?id=16531
Sep 23 2016