<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://interactiveasp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Phil Gilmore : Programming</title><link>http://interactiveasp.net/blogs/spgilmore/archive/tags/Programming/default.aspx</link><description>Tags: Programming</description><dc:language>en</dc:language><generator>CommunityServer 2008 (Build: 30417.1769)</generator><item><title>Anonymous Methods and Closures in Delphi 2010</title><link>http://interactiveasp.net/blogs/spgilmore/archive/2010/06/17/anonymous-methods-and-closures-in-delphi-2010.aspx</link><pubDate>Thu, 17 Jun 2010 23:09:00 GMT</pubDate><guid isPermaLink="false">b80005ef-4071-4968-b08e-765d7d71b33e:6660</guid><dc:creator>Phil Gilmore</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://interactiveasp.net/blogs/spgilmore/rsscomments.aspx?PostID=6660</wfw:commentRss><comments>http://interactiveasp.net/blogs/spgilmore/archive/2010/06/17/anonymous-methods-and-closures-in-delphi-2010.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/AnonymousMethodLogo2_5F00_2AF46020.png"&gt;&lt;img title="AnonymousMethodLogo2" style="border-right: 0px; border-top: 0px; display: inline; margin: 10px; border-left: 0px; border-bottom: 0px" height="116" alt="AnonymousMethodLogo2" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/AnonymousMethodLogo2_5F00_thumb_5F00_01801EE0.png" width="154" align="left" border="0" /&gt;&lt;/a&gt; 06/17/2010     &lt;br /&gt;Phil Gilmore&lt;/p&gt;  &lt;p&gt;What are anonymous methods?    &lt;br /&gt;Anonymous methods are a new language feature introduced in Delphi 2010.&amp;#160;&amp;#160; To describe them in one sentence is unfair, but I'll try.&amp;#160; They are methods which are defined inline (you might call them literal methods) and hence are not called by name.&amp;#160; Because they are not called by name they do not have names, hence the &amp;quot;anonymous&amp;quot; title.&amp;#160; &lt;/p&gt;  &lt;p&gt;Like generics they are simple enough in concept, but the reasons behind them can be elusive.&amp;#160; The application of the concept will require some real-world exposure.&amp;#160; I will start by showing them and then addressing the questions that I think will enter the reader's mind by showing ever more realistic examples.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;What do they look like?&lt;/h2&gt;  &lt;p&gt;Right off the bat, here is an example.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;procedure        &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; writeln('Anonymous method has executed');         &lt;br /&gt;end&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;This isn't very different from a normal procedure.&amp;#160; You'll notice that the procedure has no name.&amp;#160; You'll also notice the missing semicolon after the final end.&amp;#160; Without a name, we have to call them by reference.&amp;#160; To do this, we need a reference to one.&amp;#160; &lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;var        &lt;br /&gt;&amp;#160; myAnonymousMethod: TProc;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;That's easy.&amp;#160; But what's a &lt;em&gt;TProc&lt;/em&gt;?&amp;#160; Just like a reference to a procedure or procedure of object, a method reference must have a type.&amp;#160; The type must be a matching procedure or function declaration (I'll stick with procedures for now).&amp;#160; Instead of procedure or procedure of object, anonymous methods match signatures declared as &lt;em&gt;reference to procedure&lt;/em&gt;.&amp;#160; Here is the definition of &lt;em&gt;TProc&lt;/em&gt;, found in &lt;em&gt;SysUtils.pas&lt;/em&gt;:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;type         &lt;br /&gt;&amp;#160; TProc = &lt;strong&gt;&lt;font color="#ff0000"&gt;reference to&lt;/font&gt;&lt;/strong&gt; procedure;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Of course, they can also be functions and can contain parameters, following the same rules as normal methods.&amp;#160; Several are defined in &lt;em&gt;SysUtils.pas&lt;/em&gt;.&amp;#160; They are listed below.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;type        &lt;br /&gt;&amp;#160; TProc = reference to procedure;         &lt;br /&gt;&amp;#160; TProc&amp;lt;T&amp;gt; = reference to procedure (Arg1: T);         &lt;br /&gt;&amp;#160; TProc&amp;lt;T1,T2&amp;gt; = reference to procedure (Arg1: T1; Arg2: T2);         &lt;br /&gt;&amp;#160; TProc&amp;lt;T1,T2,T3&amp;gt; = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3);         &lt;br /&gt;&amp;#160; TProc&amp;lt;T1,T2,T3,T4&amp;gt; = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4);&lt;/p&gt;      &lt;p&gt;&amp;#160; TFunc&amp;lt;TResult&amp;gt; = reference to function: TResult;        &lt;br /&gt;&amp;#160; TFunc&amp;lt;T,TResult&amp;gt; = reference to function (Arg1: T): TResult;         &lt;br /&gt;&amp;#160; TFunc&amp;lt;T1,T2,TResult&amp;gt; = reference to function (Arg1: T1; Arg2: T2): TResult;         &lt;br /&gt;&amp;#160; TFunc&amp;lt;T1,T2,T3,TResult&amp;gt; = reference to function (Arg1: T1; Arg2: T2; Arg3: T3): TResult;         &lt;br /&gt;&amp;#160; TFunc&amp;lt;T1,T2,T3,T4,TResult&amp;gt; = reference to function (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4): TResult;&lt;/p&gt;      &lt;p&gt;&amp;#160; TPredicate&amp;lt;T&amp;gt; = reference to function (Arg1: T): Boolean;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;You can also define your own.&amp;#160; I've been prone to use the traditional &lt;em&gt;TGetStrProc &lt;/em&gt;for events, but this is a procedure of object and therefore does not match anonymous method types.&amp;#160; I could use &lt;em&gt;TProc&amp;lt;string&amp;gt;&lt;/em&gt;, but that's not very descriptive.&amp;#160; If I wanted something more descriptive, I could define one like this:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;type         &lt;br /&gt;&amp;#160; TAnonGetStrProc = reference to procedure(value: string);&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;h2&gt;Comparison to other method types&lt;/h2&gt;  &lt;p&gt;There are 3 basic types of subroutines in Delphi 2010.&amp;#160; Going forward, it would be useful for you to be familiar with them if you aren’t already.&amp;#160; Each of the three types are available as both procedures or as functions.&amp;#160; The first is the traditional Pascal procedure or function.&amp;#160; This is not technically a method, but can be used as a function pointer nonetheless, so I’ll cover it.&amp;#160; The second type is a regular method.&amp;#160; This is the type to which events are bound.&amp;#160; The third type is anonymous methods.&lt;/p&gt;  &lt;p&gt;Here is an example of the traditional Pascal procedure or function:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;type        &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;TWriter = procedure;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;procedure CustomWriter;            &lt;br /&gt;begin             &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160; writeln('Display this text');         &lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;end;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;var        &lt;br /&gt;&amp;#160; x: TWriter;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; x := CustomWriter;&amp;#160; &lt;br /&gt;&amp;#160; x;         &lt;br /&gt;&amp;#160; readln;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Here is an example of a method:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;type        &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;TWriter = procedure of object;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;type        &lt;br /&gt;&amp;#160; TCustomClass = class(TObject)         &lt;br /&gt;&amp;#160; public         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;procedure CustomWriter;            &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;procedure TCustomClass.CustomWriter;&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;begin            &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160; writeln('Display this text');         &lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;end;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;var        &lt;br /&gt;&amp;#160; x: TWriter;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; with TCustomClass.Create do         &lt;br /&gt;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; x := CustomWriter;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; x;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Free;         &lt;br /&gt;&amp;#160; end;         &lt;br /&gt;&amp;#160; readln;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Here is an example of an anonymous method.&amp;#160; Ignore the details for now and just pay attention to the declaration as it compares to the other two types.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;type        &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;TWriter = reference to procedure;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;var        &lt;br /&gt;&amp;#160; x: TWriter;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; x :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;procedure&amp;#160; &lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;begin            &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writeln('Display this text');         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;end;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;&amp;#160; x;        &lt;br /&gt;&amp;#160; readln;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt; We will cover the anonymous method example in the next section.&amp;#160; But for now, you can see that each of these method types has a different way of declaring its type and the actual method that matches that type’s signature is also declared differently for each type.&amp;#160; The firs two types have always been there and should be familiar to you.&amp;#160; If not, this is something you should learn before reading further.&lt;/p&gt;  &lt;h2&gt;Anonymous methods as variables&lt;/h2&gt;  &lt;p&gt;An anonymous method doesn't have a name, so it must be used with a reference.&amp;#160; That reference can be a variable to which the method is assigned.&amp;#160; Here is an example.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;var         &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;myAnonymousMethod: TProc;            &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;begin         &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;myAnonymousMethod :=&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writeln('This was written from an anonymous method');         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&lt;font color="#008000"&gt;&amp;#160; // ... &lt;/font&gt;        &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;You can now make further assignments by assigning the &lt;em&gt;myAnonymousMethod&lt;/em&gt; to another reference.&amp;#160; This reference can be another variable, a method parameter, a class field, etc.&amp;#160; As long as they are all the same type, assignments can be made as needed.&amp;#160; In this assignment, the line ends with a semicolon.&amp;#160; This semicolon is denotes the end of the assignment line itself; it is not part of the anonymous method.&amp;#160; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Invoking an anonymous method&lt;/h2&gt;  &lt;p&gt;Let's finish our variable reference example and invoke the method.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;var         &lt;br /&gt;&amp;#160; myAnonymousMethod: TProc;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; myAnonymousMethod :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writeln('This was written from an anonymous method');         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;myAnonymousMethod;&lt;/font&gt;&lt;/strong&gt;&amp;#160; &lt;font color="#008000"&gt;// Invoke the method.&lt;/font&gt;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;You can see that this code is not really useful, but it illustrates the following: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Declaration of an anonymous method reference &lt;/li&gt;    &lt;li&gt;Assignment of an anonymous method to a reference &lt;/li&gt;    &lt;li&gt;Invocation of an anonymous method through its reference. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Because anonymous methods are so natively tied to a reference, it makes sense to use them mostly where passing references is easy to do.&amp;#160; Method parameters are class fields are good examples.&amp;#160; Let's expand our example to use the &lt;em&gt;TAnonGetStrProc&lt;/em&gt; prototype and a simple logging example.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Anonymous methods as parameters&lt;/h2&gt;  &lt;p&gt;So far, our references have only been variables.&amp;#160; Modifying the variable example, we can pass a variable reference to an anonymous method as a parameter to another method.&amp;#160; This is far more useful than previous examples, as you'll see.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;type         &lt;br /&gt;&amp;#160; TAnonGetStrProc = reference to procedure(value: string);&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;type        &lt;br /&gt;&amp;#160; TMyClass = class         &lt;br /&gt;&amp;#160; public         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure DoStuff(aLogMethod: TAnonGetStrProc);         &lt;br /&gt;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160;&lt;/p&gt;      &lt;p&gt;procedure TMyClass.DoStuff(&lt;strong&gt;&lt;font color="#ff0000"&gt;aLogMethod: TAnonGetStrProc&lt;/font&gt;&lt;/strong&gt;);         &lt;br /&gt;var         &lt;br /&gt;&amp;#160; i: integer;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; try         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008000"&gt;// Throws an exception.&lt;/font&gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; i := StrToInt('invalid integer');         &lt;br /&gt;&amp;#160; except         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008000"&gt;// Log the error using the method that was passed in.          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // We don't have to define it in this class.           &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; aLogMethod('Error encountered, logged by anonymous method');         &lt;br /&gt;&amp;#160; end;         &lt;br /&gt;end;&lt;/p&gt;      &lt;p&gt;var        &lt;br /&gt;&amp;#160; LogMethod: TAnonGetStrProc;         &lt;br /&gt;begin         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160; // Log method body is defined outside of any code that uses it.&lt;/font&gt;         &lt;br /&gt;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;LogMethod :=            &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure(value: string)             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Writeln(value);             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/strong&gt;&lt;/font&gt;&lt;font color="#000000"&gt;;&amp;#160; &lt;/font&gt;&lt;font color="#008000"&gt;// Semicolon is NOT part of anonymous method.&lt;/font&gt;&lt;/p&gt;      &lt;p&gt;&lt;font color="#008000"&gt;&amp;#160; // Here, we execute some code and PASS a reference to the log method.          &lt;br /&gt;&lt;/font&gt;&amp;#160; with TMyClass.Create do         &lt;br /&gt;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DoStuff(&lt;strong&gt;&lt;font color="#ff0000"&gt;LogMethod&lt;/font&gt;&lt;/strong&gt;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Free;         &lt;br /&gt;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160; readln;&lt;/p&gt;      &lt;p&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;This is our first useful example.&amp;#160; It shows that a method can be passed around and used by other methods in other places.&amp;#160; These methods can then invoke this foreign code and pass it parameters if appropriate.&amp;#160; We have therefore illustrated inversion of control, callback functionality and code reuse.&amp;#160; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Inline declaration&lt;/h2&gt;  &lt;p&gt;In the previous example, the log method's body is defined OUTSIDE the method that calls it.&amp;#160; Instead of the reference being a local variable, it is a method parameter.&amp;#160; Okay, so what's so great about that?&amp;#160; We can define regular event methods that do that, right?&amp;#160; Remember that I said that anonymous methods are declared inline.&amp;#160; They don't have to live inside a class at all like a real method.&amp;#160; This means that we could change up the initialization section to get rid of the &lt;em&gt;LogMethod&lt;/em&gt; variable altogether.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;initialization         &lt;br /&gt;&amp;#160; with TMyClass.Create do         &lt;br /&gt;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DoStuff(         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;procedure(value: string)            &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; begin             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Writeln(value);             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; end&lt;/font&gt;&lt;/strong&gt;);&lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; Free;        &lt;br /&gt;&amp;#160; end;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;See that the first parameter is not a variable, but the procedure body itself is stuffed in the call parameter list.&amp;#160; This is the cool thing about them.&amp;#160; They can be declared on the spot and passed around like any piece of data.&amp;#160; They are first-class citizens of the Delphi language.&amp;#160; the &lt;em&gt;DoStuff&lt;/em&gt; procedure could even pass it to another method that it calls.&amp;#160; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Inversion of Control (IoC)&lt;/h2&gt;  &lt;p&gt;Let's focus on the essence of the logging example for a moment.&amp;#160; The &lt;em&gt;DoStuff&lt;/em&gt; method has the ability to log its errors.&amp;#160; It has no knowledge of how this logging is done.&amp;#160; A method was given to it which presumably knows what to do with a string it is given by the &lt;em&gt;DoStuff&lt;/em&gt; method.&amp;#160; &lt;/p&gt;  &lt;p&gt;This method may write the string to a log file on disk, write it to the Windows Event Log, a database, or send it to a logging service like SmartInspect or CodeSite.&amp;#160; This method may do nothing with the string at all.&amp;#160; The point is that the &lt;em&gt;DoStuff&lt;/em&gt; method knows nothing about that.&amp;#160; It has no control over the logging.&amp;#160; It can't decide whether to log to a file, the event log or a logging service.&amp;#160; The decision lies elsewhere.&amp;#160; This is the fundamental concept of &lt;em&gt;Inversion Of Control&lt;/em&gt; (or IoC for short).&amp;#160; &lt;/p&gt;  &lt;p&gt;Inversion of control was possible using standard function pointers, events and object methods in all previous versions of Delphi.&amp;#160; However, the concept of IoC was not in vogue until a few years ago.&amp;#160; Anonymous methods don't do anything you couldn't do before, but they can be easier than the alternatives.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Class fields&lt;/h2&gt;  &lt;p&gt;Instead of method parameters which must be passed around and can affect existing method signatures, refactoring may be done by storing anonymous methods in class fields.&amp;#160; Here is our previous example, converted.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;type         &lt;br /&gt;&amp;#160; TAnonGetStrProc = reference to procedure(value: string);&lt;/p&gt;      &lt;p&gt;type        &lt;br /&gt;&amp;#160; TMyClass = class         &lt;br /&gt;&amp;#160; protected         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;fLogMethod: TAnonGetStrProc&lt;/font&gt;&lt;/strong&gt;;         &lt;br /&gt;&amp;#160; public         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; constructor Create(aLogMethod: TAnonGetStrProc);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure DoStuff;         &lt;br /&gt;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;implementation&lt;/p&gt;      &lt;p&gt;constructor TMyClass.Create(aLogMethod: TAnonGetStrProc);        &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;fLogMethod := aLogMethod&lt;/font&gt;&lt;/strong&gt;;         &lt;br /&gt;end;&lt;/p&gt;      &lt;p&gt;procedure TMyClass.DoStuff;        &lt;br /&gt;var         &lt;br /&gt;&amp;#160; i: integer;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; try         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160; // Throws an exception. &lt;/font&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; i := StrToInt('invalid integer');         &lt;br /&gt;&amp;#160; except         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160; // Log the error. &lt;/font&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; fLogMethod('Error encountered, logged by anonymous method');         &lt;br /&gt;&amp;#160; end;         &lt;br /&gt;end;&lt;/p&gt;      &lt;p&gt;       &lt;br /&gt;initialization         &lt;br /&gt;&amp;#160; with TMyClass.Create(         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;procedure(value: string)            &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Writeln(value);             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/font&gt;&lt;/strong&gt;) do&amp;#160;&amp;#160; &lt;font color="#008000"&gt;// No semicolon after end          &lt;br /&gt;&lt;/font&gt;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DoStuff;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Free;         &lt;br /&gt;&amp;#160; end;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;In the approach above, the &lt;em&gt;DoStuff&lt;/em&gt; signature does not have to have a method parameter for the log method.&amp;#160; Instead, the method can use the &lt;em&gt;fLogMethod&lt;/em&gt; field, which is initialized in the constructor.&amp;#160; No cleanup is needed in the destructor.&amp;#160; Now any methods that you add to the class can use the log method without a special parameter just for that.&amp;#160; Most importantly, existing methods don't have to have their signatures modified when adding this log method functionality to an existing class.&amp;#160; &lt;/p&gt;  &lt;p&gt;Note too (as indicated in the comments of the above example) that the anonymous method itself is not followed by a semicolon.&amp;#160; I've mentioned this before but it can take some reminding to get used it.&amp;#160; It can be confusing because you have seen me repeatedly end an anonymous method with a semicolon, but if you go back and look, the semicolon is there to terminate the assignment of an anonymous method to a variable.&amp;#160; It is NOT part of the anonymous method itself.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Generic anonymous type declarations&lt;/h2&gt;  &lt;p&gt;Before going further, I will briefly cover the generic procedure types which I mentioned earlier.&amp;#160; In the next section, I have an example in which I use a variable declaration like this:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;var         &lt;br /&gt;&amp;#160; ShowCounter: &lt;strong&gt;&lt;font color="#ff0000"&gt;TProc&amp;lt;Integer&amp;gt;&lt;/font&gt;&lt;/strong&gt;;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;This is the notation used by generics.&amp;#160; To make sense of it, look for the declaration of &lt;em&gt;TProc&amp;lt;T&amp;gt;&lt;/em&gt; in &lt;em&gt;SysUtils.pas&lt;/em&gt;.&amp;#160; When I declare something of type TProc&amp;lt;integer&amp;gt;, it just means that I use the declaration of &lt;em&gt;TProc&amp;lt;T&amp;gt;&lt;/em&gt;, but Delphi replaces all the &lt;em&gt;T&lt;/em&gt;s in the declaration with integer when I use the &lt;em&gt;ShowCounter&lt;/em&gt; variable.&amp;#160; In other words, given this declaration:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;TProc&amp;lt;T&amp;gt; = reference to procedure (Arg1: T);&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;... my declaration of &lt;em&gt;TProc&amp;lt;integer&amp;gt;&lt;/em&gt; tells Delphi that &lt;em&gt;ShowCounter&lt;/em&gt; uses the following declaration (which the compiler creates at runtime):&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;reference to procedure (Arg1: integer);&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;This is just a way of using an existing method prototype declaration for my anonymous method instead of declaring a new one for myself.&amp;#160; It is the same as creating a new type...&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;type         &lt;br /&gt;&amp;#160; TIntegerProc = reference to procedure (Arg1: integer);&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;But because &lt;em&gt;TProc&amp;lt;T&amp;gt;&lt;/em&gt; is already declared, I can use that instead.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Closures&lt;/h2&gt;  &lt;p&gt;Before I get into closures, I want to address the constant use of the word as a misnomer.&amp;#160; The term &lt;em&gt;Closures&lt;/em&gt; is very frequently treated as a synonym for the term &lt;em&gt;anonymous methods&lt;/em&gt;.&amp;#160; Though closures are specific to anonymous methods, they are not the same concept.&amp;#160; Anonymous methods are possible without closures.&amp;#160; Do not use the terms interchangeably.&lt;/p&gt;  &lt;p&gt;You may have noticed that so far none of my examples had any variables inside the anonymous methods.&amp;#160; This is because anonymous methods have some considerations for variable scope.&amp;#160; The first rule is that all variables which are declared inside the anonymous method are safe and will adhere to all the rules with which you are familiar.&amp;#160; Variables declared outside the anonymous method are the ones you need to examine.&amp;#160; &lt;/p&gt;  &lt;p&gt;In traditional Pascal, anything in a &lt;em&gt;VAR&lt;/em&gt; block which exists physically above the code which references is visible.&amp;#160; These are called nested methods.&amp;#160; &lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;procedure OuterMethod;         &lt;br /&gt;var         &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;upperScope: string;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;&amp;#160; procedure InnerMethod;            &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160; var         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;innerScope: string;            &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160; begin         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160; // Here, upperScope and innerScope are visible.          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // lowerScope is not visible.           &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; writeln(text);         &lt;br /&gt;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;var        &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;lowerScope: string; &lt;/font&gt;&lt;/strong&gt;        &lt;br /&gt;begin         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160; // upperScope and lowerScope are visible here. &lt;/font&gt;        &lt;br /&gt;&amp;#160; InnerMethod;         &lt;br /&gt;end;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;This works because the &lt;em&gt;InnerMethod&lt;/em&gt; only lives in one place and is not visible anywhere except in the &lt;em&gt;OuterMethod&lt;/em&gt; body.&amp;#160; But when using anonymous methods, the methods can be passed to another place where the &lt;em&gt;upperScope&lt;/em&gt; variable is not declared.&amp;#160; To accommodate this, Delphi provides closures.&amp;#160; Closures create another scope which includes any symbols used by the anonymous method but which are not declared inside the method itself.&amp;#160; This scope is then bound to the anonymous method and follows it everywhere it goes.&amp;#160; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Without closures, You would use an an upper variable using parameters, like this:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;procedure TMyClass.DoStuff;         &lt;br /&gt;var         &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;j: integer&lt;/font&gt;&lt;/strong&gt;;         &lt;br /&gt;&amp;#160; ShowCounter: TProc&amp;lt;Integer&amp;gt;; &lt;font color="#008000"&gt;// We covered this type in the previous &lt;/font&gt;section.         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; ShowCounter :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure(&lt;strong&gt;&lt;font color="#ff0000"&gt;value: integer&lt;/font&gt;&lt;/strong&gt;)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // j is unknown here because it is out of scope.          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // We output a parameter instead.           &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writeln(IntToStr(value));         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160; for j := 1 to 10 do        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ShowCounter(&lt;strong&gt;&lt;font color="#ff0000"&gt;j&lt;/font&gt;&lt;/strong&gt;);&amp;#160; // Pass j as a parameter         &lt;br /&gt;end;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;You see that the anonymous method has a parameter through which I pass the current counter value.&amp;#160; The &lt;em&gt;writeln&lt;/em&gt; statement will output the value parameter instead of the &lt;em&gt;j&lt;/em&gt; variable.&amp;#160; This would be necessary because &lt;em&gt;j&lt;/em&gt; does not exist inside of the anonymous method which we assign to &lt;em&gt;ShowCounter&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;We don't have to do things that way.&amp;#160; Because Delphi provides closures, we can have direct access to &lt;em&gt;j&lt;/em&gt; counter from with the anonymous method without using a parameter.&amp;#160; Delphi will place &lt;em&gt;j&lt;/em&gt; in the scope of the method and make it available to us without any work on our part.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;procedure TMyClass.DoStuff;         &lt;br /&gt;var         &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;j: integer;&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;&amp;#160; ShowCounter: TProc; &lt;font color="#008000"&gt;// Method no longer has a parameter.          &lt;br /&gt;&lt;/font&gt;begin         &lt;br /&gt;&amp;#160; ShowCounter :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // j is known here because it is wrapped in a closure          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // and made available to us!           &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writeln(IntToStr(&lt;strong&gt;&lt;font color="#ff0000"&gt;j&lt;/font&gt;&lt;/strong&gt;));         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160; for j := 1 to 10 do        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;ShowCounter&lt;/font&gt;&lt;/strong&gt;; &lt;font color="#008000"&gt;// j is no longer passed          &lt;br /&gt;&lt;/font&gt;end;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;So now you're wondering why I just spent all this time explaining closures when it works just like a nested method anyway and you don't have to take any steps to make it work or turn it on etc.&amp;#160; The reason is because the closure is not really direct access to the symbols in the outer scope.&amp;#160; There are limitations.&amp;#160; The compiler has to make decisions about where the data comes from and what it can do with that data.&amp;#160; Sometimes it will determine that a closure is not possible and will give you an error.&amp;#160; &lt;/p&gt;  &lt;p&gt;For example, you cannot have a for loop which uses a counter which exists in the closure.&amp;#160; Again, modifying the previous example...&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;procedure TMyClass.DoStuff;         &lt;br /&gt;var         &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;j: integer;&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;&amp;#160; ShowCounter: TProc;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; ShowCounter :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;for j := 1 to 10 do            &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writeln(IntToStr(j));         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;         &lt;br /&gt;&amp;#160; ShowCounter;         &lt;br /&gt;end;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;This seems perfectly safe, but the compiler knows better.&amp;#160; Some compiler optimizations for loops require the counter to live on the stack and this one lives inside a closure instead.&amp;#160; When you run the code above, the compiler yields this error:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;[DCC Error] Project1.dpr(30): E1019 For loop control variable must be simple local variable&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;The bad news?&amp;#160; It won't work.&amp;#160; The good news?&amp;#160; There is a very good compiler error to tell you what's wrong and there is an alternate way to do the same thing.&amp;#160; The counter must be local, as the error indicates.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;procedure TMyClass.DoStuff;         &lt;br /&gt;var         &lt;br /&gt;&amp;#160; ShowCounter: TProc;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; ShowCounter :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;var j: integer;&amp;#160; &lt;/font&gt;&lt;font color="#008000"&gt;// j is now local.&lt;/font&gt;&lt;/strong&gt;&lt;font color="#008000"&gt;          &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;for j := 1 to 10 do&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writeln(IntToStr(j));         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160; ShowCounter;        &lt;br /&gt;end;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Because of such considerations, it might be a good idea to avoid closures where possible.&amp;#160; But it is important to understand how they work so that you know when you're using them.&amp;#160; Because they are so effectively transparent, a solid understanding is necessary to use or avoid them effectively.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Result in closures&lt;/h2&gt;  &lt;p&gt;The &lt;em&gt;Result&lt;/em&gt; value cannot live in a closure.&amp;#160; For example, the compiler tells you you cannot do this:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;function TMyClass.AddDays(aDays: integer): TDateTime;         &lt;br /&gt;var         &lt;br /&gt;&amp;#160; rc: TDateTime;         &lt;br /&gt;&amp;#160; p: TProc;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; rc := now;&lt;/p&gt;      &lt;p&gt;&amp;#160; p :=        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;procedure&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Result can't live in a closure.          &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;result&lt;/font&gt;&lt;/strong&gt; := rc + aDays;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160; p;        &lt;br /&gt;end;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;You get this error, again very descriptive and deliberate:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;[DCC Error] Project1.dpr(34): E2555 Cannot capture symbol 'Result'&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Instead, you must fix it like this:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;function TMyClass.AddDays(aDays: integer): TDateTime;         &lt;br /&gt;var         &lt;br /&gt;&amp;#160; rc: TDateTime;         &lt;br /&gt;&amp;#160; p: TProc;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; rc := now;&lt;/p&gt;      &lt;p&gt;&amp;#160; p :=        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // rc can live in a closure.          &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;rc&lt;/font&gt;&lt;/strong&gt; := rc + aDays;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160; p;        &lt;br /&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;result := rc&lt;/font&gt;&lt;/strong&gt;;         &lt;br /&gt;end;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Note that this means that result cannot live only in CLOSURES; the limitation does not apply to anonymous methods themselves.&amp;#160; If you are using a an anonymous function (discussed next), &lt;em&gt;result&lt;/em&gt; is allowed because it is local to the anonymous function, not something which needs to be captured in the closure.&amp;#160; Since &lt;em&gt;result&lt;/em&gt; does not apply to procedures, it is assumed that a reference to &lt;em&gt;result&lt;/em&gt; inside an anonymous procedure is an attempt to reference the return value in outer scope, hence it requires closure.&amp;#160; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Anonymous Functions&lt;/h2&gt;  &lt;p&gt;So far, I have been careful to use only anonymous procedures.&amp;#160; But as you have seen in &lt;em&gt;SysUtils.pas&lt;/em&gt;, there are also anonymous functions.&amp;#160; They work identically, except that there must be a return type in the type definition and in the inline method body itself.&lt;/p&gt;  &lt;p&gt;Here is an anonymous function type definition.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;type         &lt;br /&gt;&amp;#160; TIntegerConvertFunc = reference to &lt;strong&gt;&lt;font color="#ff0000"&gt;function&lt;/font&gt;&lt;/strong&gt;(s: string)&lt;strong&gt;&lt;font color="#ff0000"&gt;: integer;&lt;/font&gt;&lt;/strong&gt;&amp;#160; &lt;font color="#008000"&gt;// Has a return type&lt;/font&gt;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Here is an anonymous function.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;var        &lt;br /&gt;&amp;#160; myFunction: TIntegerConvertFunc;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; myfunction :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;function(s: string): integer            &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result := IntToStr(s);             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/font&gt;&lt;/strong&gt;;         &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160; // ...&lt;/font&gt;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Generic function declarations warrant mentioning.&amp;#160; We've seen the &lt;em&gt;TProc&lt;/em&gt; and &lt;em&gt;TProc&amp;lt;T&amp;gt;&lt;/em&gt; declarations in &lt;em&gt;SysUtils.pas&lt;/em&gt;.&amp;#160; However, functions have a caveat.&amp;#160; Because the functions have a return type, generic function declarations usually have a parameterized return type.&amp;#160; This means that by convention, the last parameter type of any generic function declaration is the function return type, and therefore every generic function declaration has at least one parameter because a function must always have a return type.&lt;/p&gt;  &lt;p&gt;Note that I say that this is by convention only.&amp;#160; Non-generic function declarations obviously don't apply, and even generic function declarations may have a concrete return type.&amp;#160; Furthermore, the type parameter order may not adhere to this convention.&amp;#160; You'll find that VCL and .NET both adhere to this convention.&lt;/p&gt;  &lt;p&gt;Again here is an overview of the VCL function types:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;TFunc&amp;lt;TResult&amp;gt; = reference to function: TResult;         &lt;br /&gt;TFunc&amp;lt;T,TResult&amp;gt; = reference to function (Arg1: T): TResult;         &lt;br /&gt;TFunc&amp;lt;T1,T2,TResult&amp;gt; = reference to function (Arg1: T1; Arg2: T2): TResult;         &lt;br /&gt;TFunc&amp;lt;T1,T2,T3,TResult&amp;gt; = reference to function (Arg1: T1; Arg2: T2; Arg3: T3): TResult;         &lt;br /&gt;TFunc&amp;lt;T1,T2,T3,T4,TResult&amp;gt; = reference to function (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4): TResult;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;First, note that there are no &lt;em&gt;TFunc&lt;/em&gt; declarations with no parameters.&amp;#160; That is, they all have a return type parameter.&amp;#160; The result parameter is always named &lt;em&gt;TResult&lt;/em&gt;, also by convention.&amp;#160; From top to bottom, all these function prototypes are identical except for the number of input parameters.&amp;#160; There is a function for all input parameter counts from 0 to 4.&amp;#160; If you need more than that, you can declare a new type or perhaps refactor to simplify things.&amp;#160; &lt;/p&gt;  &lt;p&gt;As an example, an anonymous method matching the last prototype might look like this:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;var         &lt;br /&gt;&amp;#160; i: integer;         &lt;br /&gt;&amp;#160; myFunction: TFunc&amp;lt;string, string, string, string, integer&amp;gt;;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; myFunction :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;function(s1, s2, s3, s4: string): integer&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; StrToInt(s1) +         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; StrToInt(s2) +         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; StrToInt(s3) +         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; StrToInt(s4);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;i := myFunction('1', '2', '3', '4');&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;&amp;#160; writeln(inttostr(i));         &lt;br /&gt;&amp;#160; readln;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;You might find, however, that using generics it is easy to simplify this example using a list.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;myFunction :=         &lt;br /&gt;&amp;#160; function&lt;strong&gt;&lt;font color="#ff0000"&gt;(aValues: TList&amp;lt;string&amp;gt;)&lt;/font&gt;&lt;/strong&gt;: integer         &lt;br /&gt;&amp;#160; var         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; j: integer;         &lt;br /&gt;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; result := 0;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for j := 0 to aValues.Count - 1 do         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result := result + StrToInt(aValues[j]);         &lt;br /&gt;&amp;#160; end;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Anonymous method names&lt;/h2&gt;  &lt;p&gt;I know... I said they don't have names.&amp;#160; More specifically, the programmer does not give them names nor can someone refer to them by name.&amp;#160; But internally, the compiler generates code for them just as any other method.&amp;#160; When it reports an error, it tries to give you some rough idea of the method to which the error applies.&amp;#160; It uses some information from its internal symbol tables to create this.&amp;#160; It is useful for you to have an idea what they look like in case you get any errors and don't know what you're seeing.&amp;#160; To see one of these, compile this code:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;var        &lt;br /&gt;&amp;#160; f: TFunc&amp;lt;integer&amp;gt;;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; f :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; function: integer         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;There is no return value in the anonymous function, so you will get a warning about it.&amp;#160; It shows you the following.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;[DCC Warning] Project1.dpr(72): W1035 Return value of function 'Project1$ActRec.$0$Body' might be undefined&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;&lt;em&gt;'Project1$ActRec.$0$Body'&lt;/em&gt; is the name that it gives to the method in the main body of a console application saved as Project1.dpr.&amp;#160; There is no predicting these names and they will change in unexplained ways between projects, etc.&amp;#160; Do not attempt to use RTTI to get a handle on these puppies by name.&amp;#160; Let the compiler keep them to itself.&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Prototype mismatch&lt;/h2&gt;  &lt;p&gt;If your anonymous method definition doesn't match the prototype of the parameter or variable to which you are assigning it, you will receive a less than perfect error.&amp;#160; For example, here is the prototype for &lt;em&gt;Generics.Defaults.TComparison&amp;lt;T&amp;gt;:&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;&amp;#160; TComparison&amp;lt;T&amp;gt; = reference to function(&lt;strong&gt;&lt;font color="#ff0000"&gt;const&lt;/font&gt;&lt;/strong&gt; Left, Right: T): Integer;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Note that the parameters are declared with the &lt;em&gt;const&lt;/em&gt; keyword.&amp;#160; If you don't notice, you might declare a method like the following and assign it to a &lt;em&gt;TComparison&amp;lt;string&amp;gt;&lt;/em&gt; variable.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;var         &lt;br /&gt;&amp;#160; c: TComparison&amp;lt;string&amp;gt;;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; c :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; function(&lt;strong&gt;&lt;font color="#ff0000"&gt;left, right: string&lt;/font&gt;&lt;/strong&gt;): integer         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (left &amp;lt; right) then result := -1         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else if (left &amp;gt; right) then result := 1         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else result := 0;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;         &lt;br /&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In this case, I get an internal error.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;[DCC Fatal Error] Project1.dpr(16): F2084 Internal Error: AV21F2707E-R0000000C-0&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;We go back to see what we did wrong and find that we left out that const keyword in the function body.&amp;#160; Furthermore, if we make this declarative mistake in other contexts, we'll get a different error.&amp;#160; In the following case (indeed most cases), we’ll get a slightly more useful error.&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;type        &lt;br /&gt;&amp;#160; TMyClass = class(TObject)         &lt;br /&gt;&amp;#160; public         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; procedure DoStuff;         &lt;br /&gt;&amp;#160; end;&lt;/p&gt;      &lt;p&gt;var        &lt;br /&gt;&amp;#160; c: TComparison&amp;lt;string&amp;gt;;         &lt;br /&gt;&lt;font color="#008000"&gt;{ TMyClass }&lt;/font&gt;&lt;/p&gt;      &lt;p&gt;procedure TMyClass.DoStuff;        &lt;br /&gt;var         &lt;br /&gt;&amp;#160; c: TComparison&amp;lt;string&amp;gt;;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; c :=         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; function(&lt;strong&gt;&lt;font color="#ff0000"&gt;left, right: string&lt;/font&gt;&lt;/strong&gt;): integer         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (left &amp;lt; right) then result := -1         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else if (left &amp;gt; right) then result := 1         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else result := 0;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end;         &lt;br /&gt;end;&lt;/p&gt;      &lt;p&gt;begin&lt;/p&gt;      &lt;p&gt;end.&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;[DCC Error] Project1.dpr(33): E2010 Incompatible types: 'TComparison&amp;lt;System.string&amp;gt;' and &lt;strong&gt;&lt;font color="#ff0000"&gt;'Procedure'&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;This error could probably use improvement because the &lt;em&gt;Procedure&lt;/em&gt; part never gets any more specific.&amp;#160; Obviously, our anonymous method isn't a procedure; it's a function.&amp;#160; So the first thing you may do is wonder if the error is referring to some other piece of code (a bug).&amp;#160; No, indeed it is referring to your anonymous function.&amp;#160; There is nothing wrong with that anonymous function by itself.&amp;#160; It just doesn't match &lt;em&gt;TComparison&amp;lt;string&amp;gt;&lt;/em&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;It would be most useful if the error read something like this instead:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;Incompatible types: 'TComparison&amp;lt;System.string&amp;gt;' and 'reference to function(string, string): integer'&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;... or even better ...&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;Incompatible types: 'reference to function(const string, const string): integer' and 'reference to function(string, string): integer'&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Again, adding the const keyword fixes it up.&amp;#160; In cases like this, copy and paste can save you some confusion.&amp;#160; It's usually a dumb mistake or oversight like that.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Predicates&lt;/h2&gt;  &lt;p&gt;A special type of method is a predicate.&amp;#160; A predicate is a filter condition.&amp;#160; This means that conventionally, the implementation of a predicate is a function with any number of parameters which returns boolean.&amp;#160; &lt;em&gt;SysUtils.pas&lt;/em&gt; defines the following for you to use for predicates:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;type         &lt;br /&gt;&amp;#160; TPredicate&amp;lt;T&amp;gt; = reference to function (Arg1: T): Boolean;&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Unfortunately, a grep reveals that this type is used nowhere in the entire VCL.&amp;#160; As useful as it is, I find it a tragedy that the new &lt;em&gt;Generics.Collections&lt;/em&gt; unit isn’t riddled with methods accepting parameters of this type.&amp;#160; That can’t stop you though.&amp;#160; Any time you want to allow a method to filter items in a collection, a predicate is a good pattern to use.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Lambda Expressions&lt;/h2&gt;  &lt;p&gt;Unfortunately, Lambda expressions are not available in Delphi.&amp;#160; While I am confident that they will be made available eventually, it is one of the features which I miss the most.&amp;#160; &lt;/p&gt;  &lt;p&gt;Because I think that it might be useful for users of other languages, I will cover them a bit here, in Prism and C# Syntax.&amp;#160; I suspect that Delphi will adhere to the Prism syntax if this feature ever appears in a future version.&lt;/p&gt;  &lt;p&gt;One of the questions that comes up when learning anonymous methods is how they can be useful when they're no less verbose as traditional methods of IoC and delegation.&amp;#160; The answer is that anonymous methods don't have to be so verbose.&amp;#160; Lambda expressions are a popular shorthand syntax for anonymous methods.&amp;#160; &lt;/p&gt;  &lt;p&gt;I do a lot of C# and have reaped the benefits of Lambda Expressions and anonymous methods together.&amp;#160; You have seen how well anonymous methods play with generics.&amp;#160; Add Lambda expressions to the mix and things get very fancy very quickly.&amp;#160; &lt;/p&gt;  &lt;p&gt;Given a function like this:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;function(s: string): integer        &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; result := StrToInt(s);         &lt;br /&gt;end;&amp;#160; &lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;There are three main parts of the function.&amp;#160; &lt;br /&gt;- The parameter list     &lt;br /&gt;- The return type     &lt;br /&gt;- The method body&lt;/p&gt;  &lt;p&gt;A Lambda expression is just a shorthand expression of these three elements.&amp;#160; The first element is a parameter list.&amp;#160; Fundamentally enclosed in parentheses, the parentheses can be omitted if there is only one parameter.&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;s: string&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;The next is the method body.&amp;#160; Because there is only one line and it is the result assignment, the assignment to result can be omitted, leaving just an expression to be evaluated.&amp;#160; Hence, the &amp;quot;&lt;em&gt;result :=&lt;/em&gt;&amp;quot; is removed, leaving:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;StrtoInt(s);&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;Put them together using the &amp;quot;hat&amp;quot; operator, which is read out loud as &amp;quot;such that&amp;quot; or &amp;quot;is a function of&amp;quot; (or whatever else you want), you get this in Prism and C#, respectively:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;&lt;font color="#008000"&gt;// Prism&lt;/font&gt;         &lt;br /&gt;s: string -&amp;gt; StrToInt(s) &lt;/p&gt;      &lt;p&gt;&amp;#160;&lt;/p&gt;      &lt;p&gt;&lt;font color="#008000"&gt;// C#          &lt;br /&gt;&lt;/font&gt;string s =&amp;gt; Int.Parse(s)&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;In C# and to some extent in Prism, the type of the parameters and the function result can be determined very effectively by the compiler based on context, alleviating the need to specify these types.&amp;#160; This is called &amp;quot;&lt;em&gt;Type Inference&lt;/em&gt;&amp;quot; and further simplifies the code:&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;       &lt;br /&gt;&lt;font color="#008000"&gt;// Prism &lt;/font&gt;        &lt;br /&gt;s -&amp;gt; StrToInt(s) &lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;&lt;font color="#008000"&gt;// C# &lt;/font&gt;        &lt;br /&gt;s =&amp;gt; Int.Parse(s)&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Multiple statements and parameters can be used, but much of the simplification goes away.&amp;#160; Here are examples again in Prism and C#, respectively.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;&lt;font color="#008000"&gt;// Prism &lt;/font&gt;        &lt;br /&gt;(s1, s2) -&amp;gt;         &lt;br /&gt;begin         &lt;br /&gt;&amp;#160; var i := StrToInt(s1) + StrToInt(s2);         &lt;br /&gt;&amp;#160; result := i;         &lt;br /&gt;end&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;&lt;code&gt;     &lt;p&gt;&lt;font color="#008000"&gt;// C# &lt;/font&gt;        &lt;br /&gt;(s1, s2) =&amp;gt;         &lt;br /&gt;{         &lt;br /&gt;&amp;#160; int i = Int.Parse(s1) + Int.Parse(s2);         &lt;br /&gt;&amp;#160; return i;         &lt;br /&gt;}&lt;/p&gt;   &lt;/code&gt;&lt;/blockquote&gt;  &lt;p&gt;While functions are usually used with Lambda expressions, procedures can be used too.&amp;#160; If the expression does not evaluate to anything, it generally requires that the result not be assigned to anything.&amp;#160; &lt;/p&gt;  &lt;p&gt;Parameterless functions and procedures can also be used.&amp;#160; Usually, an empty parameter list is provided with a pair of parentheses, ( &lt;em&gt;() –&amp;gt; …&lt;/em&gt; ).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Phil Gilmore (&lt;a href="http://www.interactiveasp.net"&gt;www.interactiveasp.net&lt;/a&gt;)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://interactiveasp.net/aggbug.aspx?PostID=6660" width="1" height="1"&gt;</description><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Programming/default.aspx">Programming</category><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Development+Tools/default.aspx">Development Tools</category><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Delphi/default.aspx">Delphi</category></item><item><title>VDUG: Delphi Generics Presentation available for download</title><link>http://interactiveasp.net/blogs/spgilmore/archive/2010/05/19/vdug-delphi-generics-presentation-available-for-download.aspx</link><pubDate>Wed, 19 May 2010 19:45:00 GMT</pubDate><guid isPermaLink="false">b80005ef-4071-4968-b08e-765d7d71b33e:6602</guid><dc:creator>Phil Gilmore</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://interactiveasp.net/blogs/spgilmore/rsscomments.aspx?PostID=6602</wfw:commentRss><comments>http://interactiveasp.net/blogs/spgilmore/archive/2010/05/19/vdug-delphi-generics-presentation-available-for-download.aspx#comments</comments><description>&lt;p&gt;05/19/2010&lt;/p&gt;  &lt;p&gt;Phil Gilmore&lt;/p&gt;  &lt;p&gt;I presented Delphi Generics for the May Virtual Delphi User Group.&amp;#160; A recording with tips ‘n tricks by Robert Love is available as a streaming video(Flash) or as a full download (MP4) at the VDUG website:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://video.vdug.org/2010/May/VDUG%20-%20May%202010.html"&gt;http://video.vdug.org/2010/May/VDUG%20-%20May%202010.html&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Phil Gilmore (&lt;a href="http://www.interactiveasp.net"&gt;www.interactiveasp.net&lt;/a&gt;)&lt;font color="#969696" size="2"&gt;&lt;font color="#969696" size="2"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://interactiveasp.net/aggbug.aspx?PostID=6602" width="1" height="1"&gt;</description><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Programming/default.aspx">Programming</category><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Development+Tools/default.aspx">Development Tools</category><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Delphi/default.aspx">Delphi</category><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Announcements/default.aspx">Announcements</category></item><item><title>Getting started with MyGeneration, a primer and tutorial</title><link>http://interactiveasp.net/blogs/spgilmore/archive/2009/12/03/getting-started-with-mygeneration-a-primer-and-tutorial.aspx</link><pubDate>Fri, 04 Dec 2009 00:36:00 GMT</pubDate><guid isPermaLink="false">b80005ef-4071-4968-b08e-765d7d71b33e:3761</guid><dc:creator>Phil Gilmore</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://interactiveasp.net/blogs/spgilmore/rsscomments.aspx?PostID=3761</wfw:commentRss><comments>http://interactiveasp.net/blogs/spgilmore/archive/2009/12/03/getting-started-with-mygeneration-a-primer-and-tutorial.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGenerationLogo2_5F00_4AC0D70B.png"&gt;&lt;img title="MyGenerationLogo2" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="244" alt="MyGenerationLogo2" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGenerationLogo2_5F00_thumb_5F00_0CC7464D.png" width="55" align="left" border="0" /&gt;&lt;/a&gt;12/03/2009&lt;/p&gt;  &lt;p&gt;Phil Gilmore&lt;/p&gt;  &lt;h2&gt;About MyGeneration&lt;/h2&gt;  &lt;p&gt;MyGeneration is a developer's code-generation tool that gives you access to your database’s schema.&amp;#160; It is useful for building O/RM entity classes based on your database schema.&lt;/p&gt;  &lt;p&gt;MyGeneration is mature, free and open-source.&amp;#160; It supports many databases.&amp;#160; It supports scripting in many languages (C# script VB.NET script, jscript, vbscript, etc.).&amp;#160; It supports output into any language.&amp;#160; You can write your own templates or use someone else’s.&amp;#160; &lt;/p&gt;  &lt;p&gt;There are many templates available.&amp;#160; Some come with the installer, but many more can be browsed and downloaded from the internet right in the MyGeneration main window.&lt;/p&gt;  &lt;p&gt;I found it easy enough to get started using someone else's downloadable templates, so I will only take a brief moment to describe that.&amp;#160; I will then spend more time explaining how to write your own templates. &lt;/p&gt;  &lt;p&gt;The MyGeneration main page is here and has the latest download link to download.com.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.mygenerationsoftware.com/portal/default.aspx"&gt;&lt;font color="#800080"&gt;http://www.mygenerationsoftware.com/portal/default.aspx&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;As the this writing, the download link points &lt;a href="http://download.cnet.com/windows/net/?tag=mncol%253Bsort&amp;amp;rpp=10&amp;amp;sort=downloadCount+asc" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; This download is an NSIS installer package.&amp;#160; I recommend installing all components.&amp;#160; &lt;/p&gt;  &lt;p&gt;When you first run MyGeneration, you are presented with the Default Settings screen.&amp;#160; The purpose of this window is to give you a place to define your database connection.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/mygeneration_5F00_defaultsettings_5F00_labeled_5F00_2963C220.png"&gt;&lt;img title="mygeneration_defaultsettings_labeled" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="273" alt="mygeneration_defaultsettings_labeled" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/mygeneration_5F00_defaultsettings_5F00_labeled_5F00_thumb_5F00_04D2349C.png" width="605" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Using the OLEDB configuration wizard (1, see image below), you can easily produce a working connection string.&amp;#160; You can also get a generic one &lt;a href="http://www.connectionstrings.com" target="_blank"&gt;here&lt;/a&gt; to get your started if you have trouble.&amp;#160; Or, enter the string manually if you have the aptitude for it.&amp;#160; However you do it, the point is to get the connection string into the connection string field (2).&lt;/p&gt;  &lt;p&gt;Once you test your connection string (3) and can connect, type a name for your connection in the box above (4) and save it (5).&amp;#160; Now you can always refer to this connection string by selecting it in the dropdown list (4) and clicking the load button.&amp;#160; Set the language mapping to your preference (i.e. C#).&amp;#160; The other settings are usually left as default.&amp;#160; Click the Save button at the top of the page and you may continue.&lt;/p&gt;  &lt;h2&gt;MyMeta&lt;/h2&gt;  &lt;p&gt;The MyMeta library is the body that fetches metadata from your database engine.&amp;#160; It’s the part that&amp;#160; must be aware of your particular database engine in order to support it.&amp;#160; You can see what MyMeta can see by opening the MyMeta browser window and viewing its tree contents.&amp;#160; If you don’t see your database schema in the MyMeta browser, your connection isn’t set up correctly or you don’t have permissions to see the things you’re looking for.&amp;#160; In any case, the data won’t be accessible for code generation unless it is visible in the MyMeta browser.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyMetaBrowser1_5F00_1970DE4D.png"&gt;&lt;img title="MyMetaBrowser1" style="border-right: 0px; border-top: 0px; display: inline; margin: 10px; border-left: 0px; border-bottom: 0px" height="158" alt="MyMetaBrowser1" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyMetaBrowser1_5F00_thumb_5F00_0008DB13.png" width="201" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Templates&lt;/h2&gt;  &lt;p&gt;There are two ways to do code generation in MyGeneration.&amp;#160; The first is to use someone else’s template.&amp;#160; The second is to write your own.&amp;#160; Most folks who are using a mainstream O/RM such as NHibernate and a mainstream language such as C# can pick a template that works with both and be done in a few minutes.&amp;#160; Others can write some templates in a few hours for any systems they want to use, as long as MyMeta supports their database engine.&lt;/p&gt;  &lt;h2&gt;Using someone else’s templates&lt;/h2&gt;  &lt;p&gt;In case you want to just get some code generation done and be done with this, I’ve put this here so you don’t have to wade through the rest of this document to get your work done.&lt;/p&gt;  &lt;p&gt;MyGeneration’s installer will give you a handful of templates that you can use.&amp;#160; These are limited and probably don’t have what you want.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGeneration_5F00_TemplateBrowser1_5F00_793C775C.png"&gt;&lt;img title="MyGeneration_TemplateBrowser1" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="291" alt="MyGeneration_TemplateBrowser1" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGeneration_5F00_TemplateBrowser1_5F00_thumb_5F00_6DA6BA1D.png" width="241" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;One of the nice things about MyGeneration is that you can browser for more templates online without leaving the application.&amp;#160; Click the globe icon in the template browser to find more templates online…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGeneration_5F00_OnlineTemplateBrowser1_5F00_49152C99.png"&gt;&lt;img title="MyGeneration_OnlineTemplateBrowser1" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="484" alt="MyGeneration_OnlineTemplateBrowser1" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGeneration_5F00_OnlineTemplateBrowser1_5F00_thumb_5F00_443278DD.png" width="152" align="left" border="0" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Now we’re talking!&amp;#160; You now have the latest templates.&amp;#160; It isn’t always easy to find what you’re looking for, but usually they’re categorized pretty well.&amp;#160; You may look for a template by the language you want to generate, or you may search by the database engine or data access framework you’re using, such as NHibernate.&lt;/p&gt;  &lt;p&gt;Double-click a template to see some pretty good detail about it if you need to know more about it.&amp;#160; When you’ve found a template you like, click the save button and continue for more templates or close the Online Template Library window when you’re done.&lt;/p&gt;  &lt;p&gt;The templates you saved will now appear in your regular Template Browser.&amp;#160; You can right-click on the desired template in the Template Browser, click EXECUTE from the popup menu, and code generation will begin.&lt;/p&gt;  &lt;p&gt;What happens at that point depends on the template.&amp;#160; Many templates will need you to give them some input parameters to do their job.&amp;#160; When this is the case, they will prompt you for parameters with their own popup form.&amp;#160; When it is complete, you will have output in the output window, or the output will be saved to a set of files.&amp;#160;&amp;#160; This is also specific to the template.&amp;#160; Most templates that output to files will prompt you for an output location.&lt;/p&gt;  &lt;p&gt;Modifying someone else’s template&lt;/p&gt;  &lt;p&gt;If you followed the steps above in “Using someone else’s templates”, you know how to get your hands on a template that you can modify.&amp;#160; Take any template in your template browser and double-click it.&amp;#160; The template can be modified right inside the MyGeneration application.&amp;#160; If you’re modifying someone else’s template, I cannot give you very specific direction.&amp;#160; From here on, I will only give direction about how to create a new template.&lt;/p&gt;  &lt;p&gt;Creating your own template&lt;/p&gt;  &lt;p&gt;Relax.&amp;#160; This really is easy.&amp;#160; You can pick from several languages and probably won’t have to learn a new language to do this.&amp;#160; There is code insight, useful error messages and bugs are easy to fix.&lt;/p&gt;  &lt;p&gt;Here some more information about MyGeneration that you will need to know.&amp;#160; First, MyGeneration has several systems.&amp;#160; We’ve already covered MyMeta, MyMeta Browser, Template Browser, and Online Template Browser.&amp;#160; There are separate help files for different systems too.&amp;#160; This is useful to know because you will be using these help files from time to time.&amp;#160; The help files really have good information, but it can be hard to find what you’re looking for, especially if you don’t know which help file to look in.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGeneration_5F00_HelpMenu_5F00_584B9566.png"&gt;&lt;img title="MyGeneration_HelpMenu" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="239" alt="MyGeneration_HelpMenu" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGeneration_5F00_HelpMenu_5F00_thumb_5F00_6CD0E4E4.png" width="213" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The systems you’re primarily concerned with are Zeus, and MyMeta.&amp;#160; Unless you are using any of the other systems listed under Help.&lt;/p&gt;  &lt;p&gt;Zeus is the scripting engine that MyGeneration uses.&amp;#160; It is the engine that takes your templates, executes them to create a program for code generation and then executes that code generation program and either passes the output back to MyGeneration or outputs it to a file (if the script tells it to).&amp;#160; Zeus can use several languages.&amp;#160; It supports C# Script, VB.Net Script, VBScript and JScript.&amp;#160; I will proceed under the assumption that you are using C# Script.&lt;/p&gt;  &lt;p&gt;MyMeta, as we have discussed, is a set of objects that your Zeus script can ask for when it needs information about your database schema.&amp;#160; There are many object types in this library and you will probably want to just browse over the help file for it to familiarize yourself with some of the interfaces that you will be using.&amp;#160; They are mostly self-evident.&lt;/p&gt;  &lt;p&gt;The Zeus engine has an output object that to which the generated code will be written.&amp;#160; This output would be sent to the Output window by default.&amp;#160; However, many templates will redirect this output to a file.&amp;#160; If that happens, the output may not appear in the output window.&lt;/p&gt;  &lt;p&gt;The Zeus engine has an input object that can be queried for parameters that the user enters are runtime.&amp;#160; Runtime is the time at which the Zeus script is executed.&amp;#160; Using the input object is optional.&lt;/p&gt;  &lt;p&gt;To create a new template, click File, then New –&amp;gt; C# Zeus Template.&amp;#160; The template will appear in a new tab on the main MyGeneration panel.&amp;#160; Inside that “Untitled” panel are 4 more tabs.&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="4" width="400" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="127"&gt;&lt;strong&gt;Tab&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="273"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="127"&gt;Template Code&lt;/td&gt;        &lt;td valign="top" width="273"&gt;You write this script.&amp;#160; This script builds the Template Source script.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="127"&gt;Interface Code&lt;/td&gt;        &lt;td valign="top" width="273"&gt;You write this script.&amp;#160; It builds a UI for gathering parameters from the user.&amp;#160; &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="127"&gt;Template Source&lt;/td&gt;        &lt;td valign="top" width="273"&gt;This script is generated and you do not touch it.&amp;#160; This is the code generation program.&amp;#160; This is the output of the Template Code script.&amp;#160; Look here if you have errors if your Template Code script.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="127"&gt;Interface Source&lt;/td&gt;        &lt;td valign="top" width="273"&gt;This script is generated and you do not touch it.&amp;#160; As the TemplateCode generates the Template Source, so too does the Interface Code generate the Interface Source.&amp;#160; Use this to debug your Interface Code.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="127"&gt;Output&lt;/td&gt;        &lt;td valign="top" width="273"&gt;If the output from the Template Source is not redirected to a file, you will see it here when you execute the template.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;As you can see, you will do your editing primarily in the template code tab.&amp;#160; If you build a UI, you will also use the interface code tab.&amp;#160; &lt;/p&gt;  &lt;p&gt;In its simplest form, a template can be comprised simply of template code which accesses the MyMeta object as input and the output object as output.&amp;#160; Next, you will want to redirect output to files, then finally build a UI.&amp;#160; The data gathered in the UI is made available to the template code via the input object.&amp;#160; &lt;/p&gt;  &lt;p&gt;Let’s start with something simple.&amp;#160; In the Template Code and Interface Code tabs, you will see some default code.&amp;#160; Keep it.&amp;#160; You will need it.&amp;#160; Run the template (F5).&amp;#160;&amp;#160; You see the output in the output tab.&amp;#160; Great!&amp;#160; Back at the Template Code window, find the Render() method.&amp;#160; This is where you will write your code.&amp;#160; It is your entry point.&amp;#160; You can write your own methods outside of it and call them from the Render method.&amp;#160; &lt;/p&gt;  &lt;h2&gt;Server tags&lt;/h2&gt;  &lt;p&gt;&amp;lt;% and %&amp;gt; tags define blocks of code within the Template Code.&amp;#160; As in ASP or JSP, this is technically a code file, but anything outside the server tags is output as a literal.&amp;#160; Note that in the Template Code window, there is literal region that looks like this:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;%&amp;gt;        &lt;br /&gt;You can toggle in and out of script like this         &lt;br /&gt;&amp;lt;%&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;Take a look at the Template Source tab.&amp;#160; You’ll see that this literal has been converted to this:&lt;/p&gt;  &lt;p&gt;output.writeln(&amp;quot;You can toggle in out of script like this&amp;quot;);&lt;/p&gt;  &lt;p&gt;To keep things simple for now, I removed indentation of this literal in the template code window.&amp;#160; You will find that line breaks and tabs will be adhered to in these literal regions.&amp;#160; For finer control, you can use direct output in the Template Code like this:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;output.writeln(&amp;quot;You can toggle in out of script like this&amp;quot;);        &lt;br /&gt;%&amp;gt;         &lt;br /&gt;You can toggle in out of script like this         &lt;br /&gt;&amp;lt;%&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;The output becomes:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;output.writeln(&amp;quot;You can toggle in out of script like this&amp;quot;);        &lt;br /&gt;output.writeln(&amp;quot;&amp;quot;);         &lt;br /&gt;output.writeln(&amp;quot;You can toggle in out of script like this&amp;quot;);&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;Of course, if you only did your literal output in this way, your template code would be identical to your template source.&amp;#160; But until you get used to it, you can do this to fine tune your whitespace.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You can also dereference a single symbol from your code without using a call to output.writeln() using the &amp;lt;%= %&amp;gt; tags.&amp;#160; For example:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;int keyCount = input.Keys.Count;        &lt;br /&gt;int j = 0;         &lt;br /&gt;foreach (string inputKey in input.Keys)         &lt;br /&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; j++;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; string inputValue = input[inputKey].ToString();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; %&amp;gt;Input key &amp;lt;%=j.ToString()%&amp;gt;&amp;lt;%         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; %&amp;gt; of &amp;lt;%=keyCount.ToString()%&amp;gt;&amp;lt;%         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; %&amp;gt;: &amp;lt;%=inputKey%&amp;gt;&amp;lt;%         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; %&amp;gt; = &amp;lt;%=inputValue%&amp;gt;&amp;lt;%=&amp;quot;\r\n&amp;quot;%&amp;gt;&amp;lt;%         &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;The Dereference Symbol tag pair is equivalent to the output.writeln.&amp;#160; Notice that you never put a semicolon between these tags.&amp;#160; To do so would generate something like this in the Template Source.&amp;#160;&amp;#160; So this tag:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;&amp;lt;%=j.ToString();%&amp;gt;&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;Would generate this:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;output.write(j.ToString(););&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;While it’s obvious to see how the premature semicolon breaks the generated code, it is still sometimes hard to remember to omit your trailing semicolons when using the Dererence Symbol tags.&amp;#160; Understanding that the text is output verbatim to an output.writeln() call makes it easier to keep things straight.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Using MyMeta&lt;/h2&gt;  &lt;p&gt;Okay, so we could output anything we want now, but we don’t have much to do without some input.&amp;#160; The input is going to start from our database schema.&amp;#160; This comes from the MyMeta object.&amp;#160; MyMeta is a global object instance of the MyMeta library and is available throughout your script.&amp;#160; Have a look at what it can do…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyMetaInsight1_5F00_01563463.png"&gt;&lt;img title="MyMetaInsight1" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="132" alt="MyMetaInsight1" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyMetaInsight1_5F00_thumb_5F00_43C8D699.png" width="319" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The databases property will give you a collection of databases.&amp;#160; From there, you can drill down into tables, columns, keys, stored procedures, etc.&amp;#160; To get a single database, first you have to access it by index from the MyMeta.Databases collection.&lt;/p&gt;  &lt;p&gt;MyMeta.Databases[&amp;quot;Northwind&amp;quot;]&lt;/p&gt;  &lt;p&gt;Type the line above in the Render method.&amp;#160; This references the Northwind database.&amp;#160; For RDBMS servers like Oracle, there may be one or many databases.&amp;#160; For local databases, this may not apply.&amp;#160; &lt;/p&gt;  &lt;p&gt;Now that we are referencing a database, you should be able to reference schema information for the tables on that database.&amp;#160; You can drill down from the database reference to its tables collection.&amp;#160; But lo, press the period key at the end of that line, and no code insight comes up.&amp;#160; The code insight is useful but limited.&amp;#160; It does not show you types, and sometimes it doesn’t know the type of the subject and can’t show its members.&amp;#160; &lt;/p&gt;  &lt;p&gt;Workaround – If you assign that reference to a strongly typed variable, the variable gives the code insight enough information to show you its members.&amp;#160; There’s just one problem.&amp;#160; You don’t know the type either.&amp;#160; You’ll have to guess.&amp;#160; This sounds terrible, but it’s not that bad.&amp;#160; Remember I said you need to be familiar with the help files?&amp;#160; Open the MyMeta help file from the MyGeneration help menu.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyMetaHelpContents_5F00_156F50EC.png"&gt;&lt;img title="MyMetaHelpContents" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="648" alt="MyMetaHelpContents" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyMetaHelpContents_5F00_thumb_5F00_257E1FA3.png" width="219" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Right there in the root you can see a list of interfaces provided by MyMeta.&amp;#160; You can easily guess which type our reference is.&amp;#160; It is an IDatabase.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyMetaInsight2_5F00_12C925EC.png"&gt;&lt;img title="MyMetaInsight2" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="144" alt="MyMetaInsight2" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyMetaInsight2_5F00_thumb_5F00_553BC822.png" width="392" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now we have the next level of code insight.&amp;#160; This is only required for code insight.&amp;#160; Instead of this (which provides code insight):&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;IDatabase db = MyMeta.Databases[&amp;quot;Northwind&amp;quot;];        &lt;br /&gt;ITable tbl = db.Tables[&amp;quot;table1&amp;quot;];         &lt;br /&gt;IColumn col = tbl.Columns[&amp;quot;id&amp;quot;];         &lt;br /&gt;output.writeln(col.Name);&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;This would work too.&amp;#160; But you have to be more familiar with MyMeta object hierarchies.&amp;#160; &lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;output.writeln(        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MyMeta         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Databases[&amp;quot;Northwind&amp;quot;]         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Tables[&amp;quot;table1&amp;quot;]         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Columns[&amp;quot;id&amp;quot;].Name         &lt;br /&gt;);&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;Most collections in MyMeta have named members and can be accessed by ordinal index or by named index:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;MyMeta.Databases[0];        &lt;br /&gt;MyMeta.Databases[“Northwind”];&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;You now have all the tools you need to build and run a useful code generation template using MyGeneration.&lt;/p&gt;  &lt;h2&gt;Redirecting output&lt;/h2&gt;  &lt;p&gt;Expect to be executing your templates repeatedly during development of the template itself and periodically during development of whatever project consumes your generated code.&amp;#160; It becomes cumbersome to copy the contents of the output window from the clipboard (MyGeneration automatically copies it to the clipboard when it writes to the output window) over to an editor to overwrite previous output.&amp;#160; It would be convenient to write output directly to a file on disk.&amp;#160; The output object can do this.&amp;#160; It can also write to multiple files.&lt;/p&gt;  &lt;p&gt;For more detail on the output object, see the Zeus help files under IZeusOutput and ZeusOutput class.&amp;#160; But here is a basic use of output to files.&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;// At first, our output buffer is empty.&amp;#160; Add something to it.        &lt;br /&gt;output.writeln(“Something”);         &lt;br /&gt;        &lt;br /&gt;// Save the current buffer to 2 different files.         &lt;br /&gt;output.save(path1, “o”);         &lt;br /&gt;output.save(path2, “o”);         &lt;br /&gt;        &lt;br /&gt;// Start a new buffer and save it to a third file.         &lt;br /&gt;output.clear();         &lt;br /&gt;%&amp;gt;Something else&amp;lt;%         &lt;br /&gt;output.save(path3, “o”);         &lt;br /&gt;        &lt;br /&gt;// Start a new buffer and since we don’t clear it, it shows up in the output window.         &lt;br /&gt;output.clear();         &lt;br /&gt;%&amp;gt;Wrote to: &amp;lt;%=path1%&amp;gt;&amp;lt;%         &lt;br /&gt;%&amp;gt;Wrote to: &amp;lt;%=path2%&amp;gt;&amp;lt;%         &lt;br /&gt;%&amp;gt;Wrote to: &amp;lt;%=path3%&amp;gt;&amp;lt;%&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;You may have noticed that I’m mixing&amp;#160; %&amp;gt;literals&amp;lt;% (outside the server code) with explicit writeln.output() calls.&amp;#160; Remember that these are interchangable and you’ll want to shoot for consistency most of the time.&amp;#160; I just mixed them up to show some variety in my examples.&lt;/p&gt;  &lt;p&gt;The second parameter of the save() method (“o”) is not documented under IZeusOutput very well.&amp;#160; They are found under the ZeusOutput class, but poorly.&amp;#160; I’ll document them here to save you time.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="4" width="400" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="77"&gt;Value&lt;/td&gt;        &lt;td valign="top" width="323"&gt;Description&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="77"&gt;“o”&lt;/td&gt;        &lt;td valign="top" width="323"&gt;Overwrites an existing file.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="77"&gt;“b”&lt;/td&gt;        &lt;td valign="top" width="323"&gt;Overwrites existing file but backs it up first.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="77"&gt;“a”&lt;/td&gt;        &lt;td valign="top" width="323"&gt;Appends an existing file.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="77"&gt;“d”&lt;/td&gt;        &lt;td valign="top" width="323"&gt;Do not overwrite (silent failure).&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Building a UI for your template.&lt;/p&gt;  &lt;p&gt;If you need parameters for your template execution they can be gathered at runtime by a UI which you build into your template.&amp;#160; The UI code is written in the editor under the Interface Code tab.&amp;#160; Again, the default sample code should be kept to get you started.&amp;#160; The Setup() method is your entry point.&amp;#160; In here, you have a global object named ui.&amp;#160; It is of type Zeus.UserInterface.GuiController.&amp;#160; You will find help for it in Zeus help under Zeus.UserInterface.&amp;#160; &lt;/p&gt;  &lt;p&gt;In a nutshell, you have some Addxxxx methods to create UI elements such as buttons and comboboxes.&amp;#160; These methods return objects of the corresponding type (IGuidButton, etc.).&amp;#160; Those objects then have layout properties such as top, bottom, width, etc.&amp;#160; To keep things simple, the IGuiController ui is very good as choosing default layout parameters for you.&amp;#160; if you add an element to the UI, it will appear in vertical order relative to other elements you have added.&amp;#160; It will fill the form horizontally.&amp;#160; While this isn’t always pretty, it makes it easy to get started.&lt;/p&gt;  &lt;p&gt;First thing’s first.&amp;#160; The interface is disabled for now.&amp;#160; Uncomment the contents of the Setup() method to see what happens.&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;public override void Setup()        &lt;br /&gt;{         &lt;br /&gt;&amp;#160; ui.Width&amp;#160; = 100;         &lt;br /&gt;&amp;#160; ui.Height = 100;         &lt;br /&gt;&amp;#160; GuiLabel lblDemo = ui.AddLabel(&amp;quot;lblDemo&amp;quot;, &amp;quot;Demo&amp;quot;, &amp;quot;Demo Tooltip&amp;quot;);         &lt;br /&gt;&amp;#160; ui.ShowGui = true;         &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGenerationDefaultUI_5F00_30AA3A9E.png"&gt;&lt;img title="MyGenerationDefaultUI" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="104" alt="MyGenerationDefaultUI" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGenerationDefaultUI_5F00_thumb_5F00_5E2B5A61.png" width="127" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;That wasn’t hard.&amp;#160; The code sizes the form (lines 1 and 2), adds a label (line 3) and displays the form (line4).&amp;#160; To expound on this, we’ll keep lines 1, 2, and 4.&amp;#160; We’ll increase the size of the form and replace line 3 with our customized form code.&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;public override void Setup()        &lt;br /&gt;{         &lt;br /&gt;&amp;#160; ui.Width&amp;#160; = 500;         &lt;br /&gt;&amp;#160; ui.Height = 300;         &lt;br /&gt;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160; // Customize things here...         &lt;br /&gt;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160; ui.ShowGui = true;         &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;Next we’ll add some controls that are actually going to be useful in this sort of project.&amp;#160; We’ll add&amp;#160; a database selection combo box and an output file selector (with labels).&amp;#160; I’ll add them to their own method to keep the Setup() method cleaner.&amp;#160; Remember that the ui object creates the controls for us.&amp;#160; This is a bit easier than MyMeta.&amp;#160; These functions have code insight that tells us the return type.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGenerationUICodeInsight1_5F00_76BAF7B1.png"&gt;&lt;img title="MyGenerationUICodeInsight1" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="41" alt="MyGenerationUICodeInsight1" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGenerationUICodeInsight1_5F00_thumb_5F00_724476EA.png" width="507" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Easy enough?&amp;#160; This won’t take long.&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;public void CreateControls()        &lt;br /&gt;{         &lt;br /&gt;&amp;#160; // Database selection drop-down.         &lt;br /&gt;&amp;#160; GuiLabel lblSelectDatabase =         &lt;br /&gt;&amp;#160;&amp;#160; ui.AddLabel(&amp;quot;lblSelectDatabase&amp;quot;, &amp;quot;Select a database:&amp;quot;, &amp;quot;&amp;quot;);         &lt;br /&gt;&amp;#160; GuiComboBox cboSelectDatabase =         &lt;br /&gt;&amp;#160;&amp;#160; ui.AddComboBox(&amp;quot;cboSelectDatabase&amp;quot;, &amp;quot;Select a database&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160; // Output file picker         &lt;br /&gt;&amp;#160; GuiLabel lblOutputFile =         &lt;br /&gt;&amp;#160;&amp;#160; ui.AddLabel(&amp;quot;lblOutputFile&amp;quot;, &amp;quot;Output filename: &amp;quot;, &amp;quot;&amp;quot;);         &lt;br /&gt;&amp;#160; GuiTextBox txtOutputFile =         &lt;br /&gt;&amp;#160;&amp;#160; ui.AddTextBox(&amp;quot;txtOutputFile&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;Output filename&amp;quot;);         &lt;br /&gt;&amp;#160; GuiFilePicker fpOutputFile =         &lt;br /&gt;&amp;#160;&amp;#160; ui.AddFilePicker(&amp;quot;fpOutputFile&amp;quot;, &amp;quot;...&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;txtOutputFile&amp;quot;, false);         &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Notice that when passing a control as a parameter to an Addxxx() method, it expects the control name as a string, not the object reference for that control.&amp;#160; To keep things straight, I always make the string ID parameter which I pass to the add method identical to the object reference to which I assign the ui element (&lt;em&gt;lblOutputfile&lt;/em&gt; = ui.AddLabel(“&lt;em&gt;lblOutputFile&lt;/em&gt;”…) for example).&lt;/p&gt;  &lt;p&gt;Well, that creates the form controls, but they have no data behind them.&amp;#160; You will frequently need to bind MyMeta elements to your UI elements.&amp;#160; We will want to do so with our database selection combo box.&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;cboSelectDatabase.BindData(MyMeta.Databases);&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;How easy was that?&amp;#160; The layout is still a little ugly, but we now have a working UI.&amp;#160; The next step is to use it from the Template Code.&amp;#160; We’ll get to that in a moment.&lt;/p&gt;  &lt;h2&gt;UI Layout&lt;/h2&gt;  &lt;p&gt;Right now, let’s fix up the layout a bit for sanity’s sake.&amp;#160; This is easy too.&amp;#160; Just set the width, height, top and left properties of each UI element.&amp;#160; You can calculate them in conjunction with the width and height properties of the ui object.&lt;/p&gt;  &lt;p&gt;Here is the finished UI.&amp;#160; As simple as it is, it may be all you need for some projects.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGenerationUIWithLayout_5F00_3FE0A36B.png"&gt;&lt;img title="MyGenerationUIWithLayout" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 10px; border-right-width: 0px" height="150" alt="MyGenerationUIWithLayout" src="http://interactiveasp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/spgilmore/MyGenerationUIWithLayout_5F00_thumb_5F00_344AE62C.png" width="500" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;public class GeneratedGui : DotNetScriptGui        &lt;br /&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // Declare UI elements in class scope.         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; GuiLabel lblSelectDatabase;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; GuiComboBox cboSelectDatabase;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; GuiLabel lblOutputFile;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; GuiTextBox txtOutputFile;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; GuiFilePicker fpOutputFile; &lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public GeneratedGui(ZeusContext context) : base(context) {} &lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; //-----------------------------------------        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // The User Interface Entry Point         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; //-----------------------------------------         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public override void Setup()         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.Width&amp;#160; = 500;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.Height = 300;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.Title = &amp;quot;Building our first UI!&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Customize things here...         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CreateControls();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LayoutControls();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DataBindControls();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.ShowGui = true;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public void CreateControls()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Database selection drop-down.         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblSelectDatabase =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.AddLabel(&amp;quot;lblSelectDatabase&amp;quot;, &amp;quot;Select a database:&amp;quot;, &amp;quot;&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cboSelectDatabase =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.AddComboBox(&amp;quot;cboSelectDatabase&amp;quot;, &amp;quot;Select a database&amp;quot;); &lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Output file picker        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblOutputFile =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.AddLabel(&amp;quot;lblOutputFile&amp;quot;, &amp;quot;Output filename: &amp;quot;, &amp;quot;&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; txtOutputFile =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.AddTextBox(&amp;quot;txtOutputFile&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;Output filename&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fpOutputFile =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.AddFilePicker(&amp;quot;fpOutputFile&amp;quot;, &amp;quot;...&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;txtOutputFile&amp;quot;, false);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void LayoutControls()         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Form         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.Width&amp;#160; = 500;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.Height = 150;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ui.Title = &amp;quot;Building our first UI!&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int margin = 12;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Position dropdown and label.         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblSelectDatabase.Width = 100;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblSelectDatabase.Left = margin;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblSelectDatabase.Top = margin;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cboSelectDatabase.Width = ui.Width         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; - lblSelectDatabase.Width - margin * 3;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cboSelectDatabase.Top = lblSelectDatabase.Top;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cboSelectDatabase.Left = lblSelectDatabase.Left         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; + lblSelectDatabase.Width + margin ;&lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Position file picker        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblOutputFile.Width = lblSelectDatabase.Width;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblOutputFile.Left = lblSelectDatabase.Left;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblOutputFile.Top = lblSelectDatabase.Top         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; + lblSelectDatabase.Height + margin;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fpOutputFile.Width = 25;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fpOutputFile.Top = lblOutputFile.Top;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fpOutputFile.Left = ui.Width - fpOutputFile.Width - margin;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; txtOutputFile.Width = ui.Width         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; - fpOutputFile.Width - lblOutputFile.Width - margin * 4;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; txtOutputFile.Top = lblOutputFile.Top;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; txtOutputFile.Left = cboSelectDatabase.Left;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public void DataBindControls()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cboSelectDatabase.BindData(MyMeta.Databases);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Consuming the UI, Method 1: Input&lt;/h2&gt;  &lt;p&gt;You have a working UI now but what good is it?&amp;#160; What does it actually do?&amp;#160; By itself, it lets you specify parameters but those parameters have to be consume by the Template Code script.&amp;#160; It does so in two ways.&amp;#160; I’ve mentioned before that the first way is through the input object.&amp;#160; The input object is also a global instance.&amp;#160; Once again, see the Zeus help file under IZeusInput and ZeusInput.&amp;#160; The input &lt;/p&gt;  &lt;p&gt;object provides the values for the UI elements as selected by the user at runtime.&amp;#160; It is more convenient than the second method, which is to access the elements themselves.&amp;#160; It is more convenient because every element has a single scalar value.&amp;#160; For example, a dropdown list has a list of elements, a selected value, a selected index, etc.&amp;#160; The input object contains a single string for that control, the selected value.&amp;#160; &lt;/p&gt;  &lt;p&gt;The input object is a collection of values, each with a name corresponding to a control on the UI form (more specifically the string ID property used in the construction of said control) and a value as entered or selected in that control at runtime.&amp;#160; Objects retrieved from this collection must be cast to specific types, usually string.&lt;/p&gt;  &lt;p&gt;Here’s an interesting exercise.&amp;#160; Put this code in your Template Code’s Render method.&amp;#160; It will output all the items in the input collection.&amp;#160; Now you’ll know exactly what’s available to you.&amp;#160; You’ll see the elements from your UI as well as several fields defined by MyGeneration.&amp;#160; MyGeneration input key names begin with double underscores.&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;&amp;#160; output.writeln(&amp;quot;Input fields: &amp;quot;);        &lt;br /&gt;&amp;#160; foreach(string s in input.Keys)         &lt;br /&gt;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160; output.write(s);         &lt;br /&gt;&amp;#160;&amp;#160; try         &lt;br /&gt;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; output.write(&amp;quot;=&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; output.write((string)input);         &lt;br /&gt;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160; catch { }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; output.writeln(&amp;quot;&amp;quot;);         &lt;br /&gt;&amp;#160; }&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;You’ll also see an entry for cboSelectDatabase.&amp;#160; It is as you selected in the UI.&amp;#160; You can now use this in your template code like this:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;IDatabase selectedDB =        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MyMeta.Databases[(string)input[&amp;quot;cboSelectDatabase&amp;quot;]];         &lt;br /&gt;output.writeln(&amp;quot;Selected database: &amp;quot; + selectedDB.Name);         &lt;br /&gt;output.writeln(&amp;quot;&amp;quot;); &lt;/p&gt;      &lt;p&gt;foreach (ITable t in selectedDB.Tables)        &lt;br /&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; output.writeln(&amp;quot;\tTable: &amp;quot; + t.Name);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach(IColumn c in t.Columns)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; output.write(&amp;quot;\t\tColumn: name=&amp;quot; + c.Name);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; output.write(&amp;quot;, dbTargetType=&amp;quot; + c.DbTargetType);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; output.write(&amp;quot;, DataType=&amp;quot; + c.DataType);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; output.write(&amp;quot;, DataTypeName=&amp;quot; + c.DataTypeName);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; output.writeln(&amp;quot;&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; output.writeln(&amp;quot;&amp;quot;);         &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;That script will output basic schema for all tables in your database.&amp;#160; &lt;/p&gt;  &lt;p&gt;Notice that when retrieving the value of the cboSelectDatabase combo box, we did not have to drill into a SelectedValue property to get the selected value.&amp;#160; The input object gives us a single string for cboSelectDatabase when we pass its name as a key.&amp;#160; The string is its selected value.&lt;/p&gt;  &lt;h2&gt;Consuming the UI, Method 2: UI&lt;/h2&gt;  &lt;p&gt;The second method is discouraged.&amp;#160; You can use the ui object to retrieve the UI elements directly and query their properties for the values you want.&amp;#160; &lt;/p&gt;  &lt;p&gt;In the previous example, we might have changed this line:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;IDatabase selectedDB =        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MyMeta.Databases[(string)input[&amp;quot;cboSelectDatabase&amp;quot;]];&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;and made it work like this:&lt;/p&gt; &lt;code&gt;   &lt;blockquote&gt;     &lt;p&gt;IDatabase selectedDB =        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MyMeta.Databases[((GuiComboBox)ui[&amp;quot;cboSelectDatabase&amp;quot;]).SelectedValue];&lt;/p&gt;   &lt;/blockquote&gt; &lt;/code&gt;  &lt;p&gt;When I change that line, the rest of the template code still works.&amp;#160; &lt;/p&gt;  &lt;p&gt;I hope this has given you everything you need to get started.&amp;#160; It certainly won’t cover everything you need to learn to achieve your particular task, but my goal was to get you started so that you would know where to look and have the tools to troubleshoot your work.&amp;#160; If I’ve left out something fundamental, please let me know.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Phil Gilmore (&lt;a href="http://interactiveasp.net/blogs/spgilmore/default.aspx" target="_blank"&gt;www.interactiveasp.net&lt;/a&gt;)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://interactiveasp.net/aggbug.aspx?PostID=3761" width="1" height="1"&gt;</description><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/MyGeneration/default.aspx">MyGeneration</category><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Programming/default.aspx">Programming</category><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://interactiveasp.net/blogs/spgilmore/archive/tags/Development+Tools/default.aspx">Development Tools</category></item></channel></rss>