www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Member delegate/fp to another member in same object?

reply Juanjo Alvarez <gorthol protonmail.com> writes:
Hi!

I would like to have a "proxy" delegate, let's call it "foo" that 
could point to a method or another, let's call them "fast_foo" or 
"slow_foo" on the same object. This way depending on some 
conditions I could switch at runtime from one set of methods to 
others with a "switchFoo(" fast") method while the rest of the 
code inside the object would continue happily calling "foo".

The problem I have is that since the delegate keep the state of 
the object at the moment of the assignment I can't use it for 
this is pretty since the "fast/slow" methods need the value of 
the members of the enclosing object members at the point of 
usage,  I guess that I could pass the "this" pointer in the 
rebinding method but since the targets are also methods of the 
same object I wouldn't be surprised to find that there is an 
obvious/elegant  way to get access to "this" on the 
delegate-pointed method implementing.

Example:

struct S {
   int someState;
   void some_foo() { return this. someState;}

   void delegate() foo;

   void enable() {
     foo = &some_foo;
   }
}

unittest {
   S s;
   s.someState = 1;
   enable();
   s.someState = 2;
   assert(foo == 2);
   // fails because the delegate keeps
   // the state of the object at the
   // assignment point
}
May 02 2017
next sibling parent Juanjo Alvarez <gorthol protonmail.com> writes:
On Tuesday, 2 May 2017 at 17:08:11 UTC, Juanjo Alvarez wrote:
 Example:

 struct S {
   int someState;
   void some_foo() { return this. someState;}

   void delegate() foo;

   void enable() {
     foo = &some_foo;
   }
 }

 unittest {
   S s;
   s.someState = 1;
   enable();
   s.someState = 2;
   assert(foo == 2);
   // fails because the delegate keeps
   // the state of the object at the
   // assignment point
 }
Forget it. I just noticed the simplified example that I just posted works (once the typo of the return value is corrected) but my more complex real code won't, will try to get a simple snippet where I can reproduce the problem.
May 02 2017
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 2 May 2017 at 17:08:11 UTC, Juanjo Alvarez wrote:
 struct S {
   int someState;
   void some_foo() { return this. someState;}

   void delegate() foo;

   void enable() {
     foo = &some_foo;
   }
 }
That's actually illegal in D. It will compile, but has undefined behavior because the compiler is free to move the struct around without giving you a chance to update the delegate. You are liable for random crashes doing that. You'd be better off using a function pointer instead of a delegate and making the user pass `this` to it explicitly, or making it a class rather than a struct, which the compiler will not move. (or a struct only ever used by pointer, a diy class basically)
May 02 2017