Anonymous Delegates
Russell Lewis
webmaster at villagersonline.com
Mon Jun 16 07:25:27 PDT 2008
Erik Lechak wrote:
> I though maybe I could do this:
> b.addOnClicked( delegate void(Button aux){
> this.doSomethingAButtonCanDo();
> } );
Not having used gtk much, I'll assume that the Button object passed to
the callback is the same button as the variable 'b' in your attempt
above. So if you want 'b' to call doSomethingAButtonCanDo() when it is
clicked, then you could write:
BEGIN CODE
b.addOnClicked(
delegate void(Button ignored)
{
b.doSomethingAButtonCanDo();
});
END CODE
or, since the argument is the same button, this also works:
BEGIN CODE
b.addOnClicked(
delegate void(Button aux)
{
aux.doSomethingAButtonCanDo();
});
END CODE
This still seems a little bit useless. But as you get more advanced,
whole new worlds open up. Let's look at how we might change the gtk API
to be more delegate-aware. Since a delegate can carry with it some
context, we could remove the Button argument from the callback:
BEGIN CODE
b.addOnClicked_noArg( &b.doSomethingAButtonCanDo );
END CODE
Notice that the syntax above constructs a delegate with 'b' as the
'this' pointer, and 'doSomethingAButtonCanDo' as the function.
The cool thing, of course, is that you can pass delegates which point to
any other type of object, so long as the delegate takes no arguments.
For instance:
BEGIN CODE
SomeWindowClass w = GetSomeSpecificWindow();
b.addOnClicked_noArg( &w.closeWindow );
END CODE
Now you see that (in D2, which has full and automatic closure support),
an anonymous delegate is just another cool thing that can be passed:
BEGIN CODE
SomeInterestingValue v = <whatever>;
SomeWindowClass w = GetSomeSpecificWindow();
b.addOnClicked_noArg({ w.setSomeProperty(v) });
END CODE
Note that in the above example, the 'this' pointer will point to the
automatically-allocated heap frame, which will store your 'v' and 'w'
variables, and when the delegate is called, that one-line function will
be executed.
In my experience, the more that I port my code (and my callbacks) to use
delegates, the more amazing things get. It's sometimes hard to see why
they are so important in trivial examples...but imagine that you were
carrying around a few dozen local variables. Then delegates (and
closures in particular) get *really* nice.
BEGIN CODE
void myFunction(<some arguments>)
{
<set some variables>
CallLibraryFunction(
delegate void(<some more arguments>)
{
<do something nontrivial which includes all the args & vars
above>
});
}
END CODE
More information about the Digitalmars-d
mailing list