In our previous episode, t...@free.fr said: > > it will be more readable (imo)? The example still does not take > > This seldom happens, but here I fully agree with Florian. ;-) Every > example of anonymous methods I have seen so far, can easily be done with > OP's procedure variables too. Maybe anonymous methods were introduced > in other languages because they didn't have something like OP's > procedure variables. I guess Object Pascal was yet again ahead of > everybody else. :)
I hinted on it in earlier procedures, but here a typical anonymous method usecase. You are in a thread and want to call a method or procedure in a different thread. (to the mainthread or a different event driven thread) BUT, the said function takes parameters. WDYD? Classically, you create some record, add all paramters to it, dump it in some queue (or argument to a windows message if you play it dirty), write a procedure in the destination thread that gets the record from the queue, and calls the function with the parameters. One can avoid doing the queue for every case by using a bit of OOP, but still you need to inherit and implement that object for every signature of a method that you want to call cross-thread this way. Loading parameters into it in the source thread, and calling the destination procedure with parameters in the execute method for the destination thread. Using the anonymous function however, you put the call within the anonymous function block. This blocks captures all necessary state, and boom it is away. Visually: Problem: call targetobject.destinationfunction(a:integer;b:someobject;c:string); in a different thread. Classic solution: type // for every signature: TMyobject = class(TpseudoClosure) a:integer; b:someobject; c:string; tgob: TTargetObject; procedure execute; override; end; procedure TMyObject.Execute; begin tgob.destinationfunction(a,b,c); end; // once: var thrqueue :TSomeGenericThreadsafeQUeue<TPseudoClosure>; procedure tmythread.syncfunc; var x:TPseudoClosure; begin x:=getqueuecurrentthread().popitem; // get closure object from queue x.execute; x.free; end; // calling from source thread; var x : TPseudoclosure x:=TMyObject.Create; x.a:=a; x.b:=b; x.c:=c; tboj:=targetobject; queuefortargetthread.pushitem(x); queuefortargetthread.queue(syncfunc); // call item async in other thread. // tthread.queue not yet in FPC I have many such constructs in my current framework. Of course you start to double use simple objects, and not all cases use 3 parameters. It is just for the idea. Note that tabstractclosure, the generic queue etc must also be defined, but that is so general it could be in the RTL, and not a burden --------------------------------- vs -~------------------------------- Equivalent solution with anon functions: targethread.queue( procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string) begin targetobject.destinationprocedure(a,b,c); end; Note how common this looks compared to the original. Btw: I don't know this function this well. I only described it how I saw it in several D2010 blogs. I still support D2009, and the framework design was even older, so I don't actively use it. _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal