www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - delegate !is null

reply "Saaa" <empty needmail.com> writes:
class C
{
  private int i;
  int method()
  {
    return i;
  }
}

class D
{
  private int delegate(void) _deleg;
  this(int delegate(void) d)
  {
    _deleg = d;
  }
  void write()
  {
    if(_deleg !is null)
    }
      writef(_deleg());
    }
  }
}
C c = null;
D d = new d;
d.function(c.method());
//This fails, as method is not availible for null.
d.function({return c.method();});
//This works but now I can't check whether c is null or not.
d.write(); //will fail.

Any suggestions? 
Sep 04 2009
next sibling parent "Saaa" <empty needmail.com> writes:
D should be like this :)
class D
{
  private int delegate(void) _deleg;
  private int _value; //
  this(int delegate(void) d)
  {
    _deleg = d;
  }
  void write()
  {
    if(_deleg !is null)
    }
      _value = _deleg(); //
    }
    writefln(_value); //
  }
} 
Sep 04 2009
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 04 Sep 2009 14:33:12 -0400, Saaa <empty needmail.com> wrote:

 class C
 {
   private int i;
   int method()
   {
     return i;
   }
 }

 class D
 {
   private int delegate(void) _deleg;
   this(int delegate(void) d)
   {
     _deleg = d;
   }
   void write()
   {
     if(_deleg !is null)
     }
       writef(_deleg());
     }
   }
 }
 C c = null;
 D d = new d;
 d.function(c.method());
 //This fails, as method is not availible for null.
 d.function({return c.method();});
 //This works but now I can't check whether c is null or not.
 d.write(); //will fail.

 Any suggestions?
Maybe you could rephrase your question in english. I can't really understand what you are trying to do with this code. i.e. "I want to be able to tell whether a delegate is null or not, how do I do that". But you do that just like you said -- dg !is null. -Steve
Sep 04 2009
parent reply "Saaa" <empty needmail.com> writes:
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message 
news:op.uzqxxo1neav7ka localhost.localdomain...
 On Fri, 04 Sep 2009 14:33:12 -0400, Saaa <empty needmail.com> wrote:

 class C
 {
   private int i;
   int method()
   {
     return i;
   }
 }

 class D
 {
   private int delegate(void) _deleg;
   this(int delegate(void) d)
   {
     _deleg = d;
   }
   void write()
   {
     if(_deleg !is null)
     }
       writef(_deleg());
     }
   }
 }
 C c = null;
 D d = new d;
 d.function(c.method());
 //This fails, as method is not availible for null.
 d.function({return c.method();});
 //This works but now I can't check whether c is null or not.
 d.write(); //will fail.

 Any suggestions?
Maybe you could rephrase your question in english. I can't really understand what you are trying to do with this code. i.e. "I want to be able to tell whether a delegate is null or not, how do I do that". But you do that just like you said -- dg !is null. -Steve
(unexpected visit this weekend) Erm, like this.. ? I'd like to set D's delegate to a method which is not yet available (like c.method). I solved this by encapsulating the method within a function literal, but I also need to know whether the method is available or not when calling the delegate. I could do this by making the function literal include the null-checking code, but is there maybe a better solution to this problem? The delegate is supposed to change a variable within the D class. Hope you understand it :)
Sep 06 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 06 Sep 2009 18:54:47 -0400, Saaa <empty needmail.com> wrote:

 I'd like to set D's delegate to a method which is not yet available (like
 c.method).
 I solved this by encapsulating the method within a function literal, but  
 I
 also need to know whether
 the method is available or not when calling the delegate.
 I could do this by making the function literal include the null-checking
 code, but is there maybe a better solution to this problem?
 The delegate is supposed to change a variable within the D class.
 Hope you understand it :)
A delegate is a struct with a data pointer and a function pointer. You can access the individual parts via .ptr and .func (I believe). You can even change them via those properties. does that help? -Steve
Sep 08 2009
parent reply "Saaa" <empty needmail.com> writes:
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message 
news:op.uzxs4wyreav7ka localhost.localdomain...
 On Sun, 06 Sep 2009 18:54:47 -0400, Saaa <empty needmail.com> wrote:

 I'd like to set D's delegate to a method which is not yet available (like
 c.method).
 I solved this by encapsulating the method within a function literal, but 
 I
 also need to know whether
 the method is available or not when calling the delegate.
 I could do this by making the function literal include the null-checking
 code, but is there maybe a better solution to this problem?
 The delegate is supposed to change a variable within the D class.
 Hope you understand it :)
A delegate is a struct with a data pointer and a function pointer. You can access the individual parts via .ptr and .func (I believe). You can even change them via those properties. does that help? -Steve
I did read that part. The problem lies more in that I'd like to point to something which is not there yet. In the code 'c.method()' is not there yet, as c is null. Maybe I should create a dummy object for c to point to in stead of null ? That way I point the delegate to the dummy method and ignore it as long as it is pointing to the dummy method :) The only drawback to this is that all objects I want to point the delegate to, need to somehow be convertable to the dummy type (interface/abstract class), meaning it will be less flexible.
Sep 08 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 08 Sep 2009 09:22:30 -0400, Saaa <empty needmail.com> wrote:

 "Steven Schveighoffer" <schveiguy yahoo.com> wrote in message
 news:op.uzxs4wyreav7ka localhost.localdomain...
 On Sun, 06 Sep 2009 18:54:47 -0400, Saaa <empty needmail.com> wrote:

 I'd like to set D's delegate to a method which is not yet available  
 (like
 c.method).
 I solved this by encapsulating the method within a function literal,  
 but
 I
 also need to know whether
 the method is available or not when calling the delegate.
 I could do this by making the function literal include the  
 null-checking
 code, but is there maybe a better solution to this problem?
 The delegate is supposed to change a variable within the D class.
 Hope you understand it :)
A delegate is a struct with a data pointer and a function pointer. You can access the individual parts via .ptr and .func (I believe). You can even change them via those properties. does that help? -Steve
I did read that part. The problem lies more in that I'd like to point to something which is not there yet. In the code 'c.method()' is not there yet, as c is null. Maybe I should create a dummy object for c to point to in stead of null ? That way I point the delegate to the dummy method and ignore it as long as it is pointing to the dummy method :) The only drawback to this is that all objects I want to point the delegate to, need to somehow be convertable to the dummy type (interface/abstract class), meaning it will be less flexible.
Hm... I'm still confused. Why not just set the delegate to null? Why do you need to have the delegate set to something? There are ways to do it, without having a class instance, but it is messy. -Steve
Sep 08 2009
parent reply "Saaa" <empty needmail.com> writes:
 The problem lies more in that I'd like to point to something which is not
 there yet.
 In the code 'c.method()' is not there yet, as c is null.
 Maybe I should create a dummy object for c to point to in stead of null ?
 That way I point the delegate to the dummy method and ignore it as long 
 as
 it is pointing
 to the dummy method :)
 The only drawback to this is that all objects I want to point the 
 delegate
 to,
 need to somehow be convertable to the dummy type (interface/abstract 
 class),
 meaning it will be less flexible.
Hm... I'm still confused. Why not just set the delegate to null? Why do you need to have the delegate set to something?
It is for the gui. I give it a list of things to display. And some of these things don't yet exist or can be deleted at any time. I'd like it to display the last valid value.
 There are ways to do it, without having a class instance, but it is messy.
how messy? :D Kind of related: If you delete an object and later create a new object, what are the chances they are located on the same place (deleted.ptr is new.ptr) ? Does the garbage collector try to reuse locations or is it the opposite (or random) ?
Sep 08 2009
next sibling parent reply div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Saaa wrote:
 The problem lies more in that I'd like to point to something which is not
 there yet.
 In the code 'c.method()' is not there yet, as c is null.
 Maybe I should create a dummy object for c to point to in stead of null ?
 That way I point the delegate to the dummy method and ignore it as long 
 as
 it is pointing
 to the dummy method :)
 The only drawback to this is that all objects I want to point the 
 delegate
 to,
 need to somehow be convertable to the dummy type (interface/abstract 
 class),
 meaning it will be less flexible.
Hm... I'm still confused. Why not just set the delegate to null? Why do you need to have the delegate set to something?
It is for the gui. I give it a list of things to display. And some of these things don't yet exist or can be deleted at any time. I'd like it to display the last valid value.
 There are ways to do it, without having a class instance, but it is messy.
how messy? :D
The only way I've found so far to do static binding like you are talking about is using string mixins. My port of Atl's window classes uses a MFC like message map: mixin messageMap!( msgRangeHdlr!(WM_MOUSEFIRST, WM_MOUSELAST, "wmMouseEvents"), msgHdlr!(WM_PAINT, "wmPaint"), msgHdlr!(WM_SIZE, "wmSize"), msgHdlr!(WM_KEYUP, "wmKeyUp"), msgHdlr!(WM_CHAR, "wmChar"), msgHdlr!(WM_SHOWWINDOW, "wmShow"), msgHdlr!(WM_CLOSE, "wmClose"), msgHdlr!(WM_CREATE, "wmCreate") ); Having to put the classes method in a string is a bit ugly, but without c++ style pointer to members I don't see any other way of doing it. If you want to have a look in more detail: http://www.sstk.co.uk/atlWinD.php
 Kind of related:
 If you delete an object and later create a new object, what are the chances 
 they are located on the
 same place (deleted.ptr is new.ptr) ?
 Does the garbage collector try to reuse locations or is it the opposite (or 
 random) ? 
Dunno, but the full source code is in dmd zip src\druntime\src\gc\basic\gcx.d if you are really that interested. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFKppg7T9LetA9XoXwRApS4AJ0f+SI6MhonTiwLqC6LPD1lq4GzUACfU/oC TY+3D6isjNKUt9zVxgoSDJ4= =foxA -----END PGP SIGNATURE-----
Sep 08 2009
parent reply "Saaa" <empty needmail.com> writes:
 The only way I've found so far to do static binding like you are talking
 about is using string mixins.
I need to rethink stuff a bit, but mixins might be the solution.
 My port of Atl's window classes uses a MFC
 like message map:

 mixin messageMap!(
  msgRangeHdlr!(WM_MOUSEFIRST, WM_MOUSELAST, "wmMouseEvents"),
  msgHdlr!(WM_PAINT, "wmPaint"),
  msgHdlr!(WM_SIZE, "wmSize"),
  msgHdlr!(WM_KEYUP, "wmKeyUp"),
  msgHdlr!(WM_CHAR, "wmChar"),

  msgHdlr!(WM_SHOWWINDOW, "wmShow"),
  msgHdlr!(WM_CLOSE, "wmClose"),
  msgHdlr!(WM_CREATE, "wmCreate")
 );

 Having to put the classes method in a string is a bit ugly, but without
 c++ style pointer to members I don't see any other way of doing it.

 If you want to have a look in more detail:

 http://www.sstk.co.uk/atlWinD.php
The zip 404ed
 Kind of related:
 If you delete an object and later create a new object, what are the 
 chances
 they are located on the
 same place (deleted.ptr is new.ptr) ?
 Does the garbage collector try to reuse locations or is it the opposite 
 (or
 random) ?
Dunno, but the full source code is in dmd zip src\druntime\src\gc\basic\gcx.d if you are really that interested.
nah :) bit beyond me anyway I'm afraid.
Sep 08 2009
parent div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Saaa wrote:
 The only way I've found so far to do static binding like you are talking
 about is using string mixins.
I need to rethink stuff a bit, but mixins might be the solution.
 My port of Atl's window classes uses a MFC
 like message map:

 mixin messageMap!(
  msgRangeHdlr!(WM_MOUSEFIRST, WM_MOUSELAST, "wmMouseEvents"),
  msgHdlr!(WM_PAINT, "wmPaint"),
  msgHdlr!(WM_SIZE, "wmSize"),
  msgHdlr!(WM_KEYUP, "wmKeyUp"),
  msgHdlr!(WM_CHAR, "wmChar"),

  msgHdlr!(WM_SHOWWINDOW, "wmShow"),
  msgHdlr!(WM_CLOSE, "wmClose"),
  msgHdlr!(WM_CREATE, "wmCreate")
 );

 Having to put the classes method in a string is a bit ugly, but without
 c++ style pointer to members I don't see any other way of doing it.

 If you want to have a look in more detail:

 http://www.sstk.co.uk/atlWinD.php
The zip 404ed
Typeof. doh. fixed. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFKpuNnT9LetA9XoXwRAuutAKC0q9CzjrH37nOXhg5eJNaWMw1X8wCdFa0P QNhCcfUJamdDdU2/n6LAg/U= =B9aH -----END PGP SIGNATURE-----
Sep 08 2009
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 08 Sep 2009 12:40:13 -0400, Saaa <empty needmail.com> wrote:

 Hm... I'm still confused.  Why not just set the delegate to null?  Why  
 do
 you need to have the delegate set to something?
It is for the gui. I give it a list of things to display. And some of these things don't yet exist or can be deleted at any time. I'd like it to display the last valid value.
That still doesn't explain why you need to have delegates set to something valid, yet have a null pointer value. Either a) you are trying to subvert the type system, or b) you can simply set the whole delegate (function and pointer) once you get the class instance. It's hard for me to say what is the best way to do it, but generally, things like this are difficult, and rightfully so. Having a delegate without a valid pointer makes little sense.
 There are ways to do it, without having a class instance, but it is  
 messy.
how messy? :D
class C { int val = 0; int method() {return val;} } int delegate() dg; dg.func = &C.method; // note the upper-case C // dg is now a "instanceless" delegate to C.method. dg.ptr = new C; Now you can call dg() and it will call the C.method function on the newly created C object. Note that this method of manipulating methods does NOT obey inheritance. For example: class B : C { int method() {return 555;} } dg.ptr = new B; dg(); // will return 0, since it calls C's version of method. I also don't know how well it will work on interfaces.
 Kind of related:
 If you delete an object and later create a new object, what are the  
 chances
 they are located on the
 same place (deleted.ptr is new.ptr) ?
 Does the garbage collector try to reuse locations or is it the opposite  
 (or
 random) ?
The chances are non-zero :) I wouldn't depend on this behavior either way if I were you. -Steve
Sep 08 2009
parent reply "Saaa" <empty needmail.com> writes:
 Hm... I'm still confused.  Why not just set the delegate to null?  Why
 do
 you need to have the delegate set to something?
It is for the gui. I give it a list of things to display. And some of these things don't yet exist or can be deleted at any time. I'd like it to display the last valid value.
That still doesn't explain why you need to have delegates set to something valid, yet have a null pointer value. Either a) you are trying to subvert the type system, or b) you can simply set the whole delegate (function and pointer) once you get the class instance. It's hard for me to say what is the best way to do it, but generally, things like this are difficult, and rightfully so. Having a delegate without a valid pointer makes little sense.
 There are ways to do it, without having a class instance, but it is 
 messy.
how messy? :D
class C { int val = 0; int method() {return val;} } int delegate() dg; dg.func = &C.method; // note the upper-case C
That's actually quite nice, I didn't know it worked like that :)
 // dg is now a "instanceless" delegate to C.method.

 dg.ptr = new C;
So, nothing special under the hood, this would also work? C c= new C; dg.ptr = c;
 Now you can call dg() and it will call the C.method function on the newly 
 created C object.

 Note that this method of manipulating methods does NOT obey inheritance. 
 For example:

 class B : C
 {
   int method() {return 555;}
 }

 dg.ptr = new B;

 dg(); // will return 0, since it calls C's version of method.

 I also don't know how well it will work on interfaces.
Very nice :) Might be useful, thanks.
 Kind of related:
 If you delete an object and later create a new object, what are the 
 chances
 they are located on the
 same place (deleted.ptr is new.ptr) ?
 Does the garbage collector try to reuse locations or is it the opposite 
 (or
 random) ?
The chances are non-zero :)
Are you quite sure there? I'm only asking a single 'new'. I mean, there could be some heuristic which would prevent the a new object to take the place of the latest deleted one.
 I wouldn't depend on this behavior either way  if I were you.
Yeah you're right, as long as something like this isn't part of the spec it wouldn't be safe. Plus it shouldn't be part of the spec as it would be too stringent on the gc implementation in my opinion. Just curious :)
Sep 08 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 08 Sep 2009 16:15:49 -0400, Saaa <empty needmail.com> wrote:


 // dg is now a "instanceless" delegate to C.method.

 dg.ptr = new C;
So, nothing special under the hood, this would also work? C c= new C; dg.ptr = c;
Yes, same thing.
 I also don't know how well it will work on interfaces.
Very nice :) Might be useful, thanks.
Just be cautious. You can get into undefined territory real easily, because dg.ptr is a void * (i.e. goodbye type system, I'm on my own!)
 Kind of related:
 If you delete an object and later create a new object, what are the
 chances
 they are located on the
 same place (deleted.ptr is new.ptr) ?
 Does the garbage collector try to reuse locations or is it the opposite
 (or
 random) ?
The chances are non-zero :)
Are you quite sure there?
very quite.
 I'm only asking a single 'new'.
 I mean, there could be some heuristic which would prevent the a new  
 object
 to take the place of the latest deleted one.
There isn't. Memory freed by the GC is able to be used in another allocation. If this didn't happen, then it wouldn't take long to use up all the memory in the system. I'm sure if you threw random shit at the GC long enough, it would do this :) -Steve
Sep 08 2009
parent "Saaa" <empty needmail.com> writes:
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message 
news:op.uzyfzuvueav7ka localhost.localdomain...
 On Tue, 08 Sep 2009 16:15:49 -0400, Saaa <empty needmail.com> wrote:


 // dg is now a "instanceless" delegate to C.method.

 dg.ptr = new C;
So, nothing special under the hood, this would also work? C c= new C; dg.ptr = c;
Yes, same thing.
 I also don't know how well it will work on interfaces.
Very nice :) Might be useful, thanks.
Just be cautious. You can get into undefined territory real easily, because dg.ptr is a void * (i.e. goodbye type system, I'm on my own!)
Ok, noted.
 Kind of related:
 If you delete an object and later create a new object, what are the
 chances
 they are located on the
 same place (deleted.ptr is new.ptr) ?
 Does the garbage collector try to reuse locations or is it the opposite
 (or
 random) ?
The chances are non-zero :)
Are you quite sure there?
very quite.
 I'm only asking a single 'new'.
 I mean, there could be some heuristic which would prevent the a new 
 object
 to take the place of the latest deleted one.
There isn't. Memory freed by the GC is able to be used in another allocation. If this didn't happen, then it wouldn't take long to use up all the memory in the system.
I didn't say a second new couldn't take the place of the delete ;)
 I'm sure if you threw random shit at the GC  long enough, it would do this 
 :)

 -Steve 
Sep 08 2009
prev sibling parent reply "Saaa" <empty needmail.com> writes:
Hope this one makes any sense :)

C c = new C;
C mouseOverObject = c;

int delegate() deleg = &mouseOverObject.getSomeVariable;
mouseOverObject = null;

int value;
void write()
{
if(deleg !is null) //how do I make this check for (mouseOverObject !is 
null)?
{
value = deleg();
}
writefln( value);
}

mainloop:
... code which may change mouseOverObject to be null or any C object
write();
goto mainloop; 
Sep 08 2009
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 08 Sep 2009 18:13:56 -0400, Saaa <empty needmail.com> wrote:

 Hope this one makes any sense :)

 C c = new C;
 C mouseOverObject = c;

 int delegate() deleg = &mouseOverObject.getSomeVariable;
 mouseOverObject = null;

 int value;
 void write()
 {
 if(deleg !is null) //how do I make this check for (mouseOverObject !is
 null)?
if(mouseOverObject !is null) That's the only way. A delegate does not magically become set to null when you set the original object to null or delete the original object. It is a separate pointer that is only set when you set it. What you are asking is the equivalent of this: int x = 5; int y = x; x = 0; if(y != 0) // how do I check through y that x is now 0? However, setting mouseOverObject to null does *not* destroy the object, as long as the delegate exists, it is still pointing to the object, so it will not be cleaned by the GC. So your delegate is still valid as long as you don't delete mouseOverObject manually. -Steve
Sep 10 2009