<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Jamie's Blog</title>
	
	<link>http://jamiei.com/blog</link>
	<description>Delphi Programming, Web Development, General Technology and, of course, Midget Gems</description>
	<lastBuildDate>Sun, 22 Nov 2009 18:55:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain="jamiei.com" port="80" path="/blog/?rsscloud=notify" registerProcedure="" protocol="http-post" />
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/NullReference" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="nullreference" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>An Improved Cirrus Caching Aspect</title>
		<link>http://jamiei.com/blog/2009/11/an-improved-cirrus-caching-aspect/</link>
		<comments>http://jamiei.com/blog/2009/11/an-improved-cirrus-caching-aspect/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 09:30:24 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi Prism]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[cirrus]]></category>
		<category><![CDATA[delphi prism]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=496</guid>
		<description><![CDATA[In my original introduction to Cirrus framework I drew up a basic method result caching attribute for Delphi Prism. This weekend I thought I&#8217;d give it another go and try to create a more general purpose Caching Aspect that integrates with a well known Cache library. I decided to use the opportunity to experiment with [...]]]></description>
			<content:encoded><![CDATA[<p>In my original <a href="http://jamiei.com/blog/2009/06/delphi-prism-cirrus-framework/">introduction to Cirrus framework</a> I drew up a basic method result caching attribute for Delphi Prism. This weekend I thought I&#8217;d give it another go and try to create a more general purpose Caching Aspect that integrates with a well known Cache library. I decided to use the opportunity to experiment with the <a href="http://msdn.microsoft.com/en-us/library/dd203226.aspx">Caching Application Block</a> from the <a href="http://msdn.microsoft.com/en-us/library/dd203099.aspx">Microsoft Patterns and Practice Enterprise Library</a> which you should definitely <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=1643758B-2986-47F7-B529-3E41584B6CE5&amp;displaylang=en">download</a> and do some research into if you haven&#8217;t already.</p>
<p>Last time, I had created an attribute which could only be attached to methods returning strings and used a home-made caching class, the Aspect looked like this:</p>
<pre class="brush: delphi; collapse: true; light: false; toolbar: true;">
namespace AOPCacheLibrary;

interface

uses
  RemObjects.Oxygene.Cirrus.*,
  RemObjects.Oxygene.Aspects;

type
   [AttributeUsage(AttributeTargets.Method)]
  MemCacheAttribute = public class(System.Attribute, IMethodImplementationDecorator)
  private
  public

    method HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
  end;

implementation

method MemCacheAttribute.HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
begin
  // Get a Reference to our Result Value
  var newResult := new ResultValue();

  // Get our MemCache Object
  var cacheType := Services.FindType('AOPCacheLibrary.MemCache');
  // Setup our static methods.
  var getDataProc := new ProcValue(new TypeValue(cacheType), 'getData', [new NamedLocalValue('cacheKey')]);

  // Assign the result of our cache request to a local variable.
  var getDataAssignment := new AssignmentStatement(new NamedLocalValue('strData'), getDataProc);

  // CACHE DATA USED: To assign our Cache'd data to the Method Result
  var useCacheData := new AssignmentStatement(newResult, new NamedLocalValue('strData'));
  // CACHE DATA NOT USED: To assign the result of our OriginalBody to the Method Result.
  var useOriginalMethodResult := new AssignmentStatement(new NamedLocalValue('resultOriginal'), newResult);

  aMethod.SetBody(Services,
    method begin
      var strData: String;
      // Get our Cache Key Name
      var cacheKey := MemCache.getKeyFromMethod(Aspects.MethodName, Aspects.GetParameters);

      try
        // See if we have anything in the cache for this key.
        unquote(getDataAssignment);
        // Replace this
        unquote(useCacheData);
      except
        on E: Exception do
        begin
          var resultOriginal: String;
          // No cache data found, execute the original method body.
          Aspects.OriginalBody;

          // Assign the result of the Original Method to a new variable.
          unquote(useOriginalMethodResult);
          // Send the result of the Original Method to the Cache for next time.
          MemCache.setData(cacheKey, resultOriginal);
        end;
      end;
    end);
end;

end.
</pre>
<p>Modifying my original code into working with the Microsoft Enterprise Caching black wasn&#8217;t particularly hard. If you haven&#8217;t worked with the Microsoft P&amp;P Enterprise Library Caching Block before I highly recommend the <a href="http://msdn.microsoft.com/en-us/library/dd203278.aspx">Quickstart guide</a>. The Enterprise Caching Block allows you to <a href="http://msdn.microsoft.com/en-us/library/dd203112.aspx">configure your cache using configuration file</a> and change the backing store to suit own your needs. I would certainly recommend tweaking the expiration time and frequency of cache cleaning times before you begin.</p>
<p>Whilst rewriting the code of my Aspect I found it absolutely invaluable to have the <a href="http://prismwiki.codegear.com/en/Cirrus">Cirrus documentation wiki</a> open and a piece of paper next to my keyboard with the approximate psuedo-code that I was intending to build with Cirrus written on it. I did actually find that despite the fact that the code I was building was not complicated, I did require a reminder of the statements and structure of it.</p>
<p>One additional problem that I did encounter very quickly on my modification was that I had a method which would generate a string key from the method name being called and its parameters which looked like this:</p>
<pre class="brush: delphi;">
class method CacheKeyFactory.GetKeyFromMethod(aName: String; Args: Array of object): String;
begin
  var argConcat: String;

  argConcat := aName;
  for argTemp in Args do
  begin
    argConcat := argConcat + argTemp.ToString();
  end;

  Result := argConcat;
end;
</pre>
<p>Which I had intended to inject into the target class using the <a href="http://prismwiki.codegear.com/en/AutoInjectIntoTargetAttribute_Class">AutoInjectIntoTargetAttribute</a> which as the name suggests creates the method tagged within the class you are targetting with your attribute. The problem I encountered was that I used this Attribute on a method within an <a href="http://prismwiki.codegear.com/en/Cirrus_Overview">IMethodImplementationDecorator</a> attribute which meant that it worked perfectly when I applied my attribute to just one method within a class but applying my attribute to more than one meant that the AutoInjected method got injected more than once &#8211; causing a conflict (<em>Is this a bug? I was told not but it seems odd to me</em>).</p>
<p><em>[Update: 22/11/2009] I have reported this issue as QC: </em><a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=79705"><em>79705</em></a><em>. [/Update]</em></p>
<p>Therefore as a workaround, I was forced to move this key generating method into a static class elsewhere in the assembly but maybe someone can work out a way around this limitation.</p>
<p>I also encountered an annoying trait of the Cirrus Framework which is that some errors produce a fairly unhelpful message and lead you to a line in the Project&#8217;s build file which whilst being logical can be infuriating when you&#8217;re presented with this:</p>
<div id="attachment_505" class="wp-caption aligncenter" style="width: 310px"><a href="http://jamiei.com/blog/wp-content/uploads/2009/11/CirrusExceptionHandling.png"><img class="size-medium wp-image-505" title="CirrusExceptionHandling" src="http://jamiei.com/blog/wp-content/uploads/2009/11/CirrusExceptionHandling.png" alt="A rather confusing exception and causal code identification." width="300" height="181" /></a><p class="wp-caption-text">A rather confusing exception and causal code identification.</p></div>
<p>After a tiny bit of tweaking, My next iteration of the Caching Attribute looks like this:</p>
<pre class="brush: delphi;">

type
  [AttributeUsage(AttributeTargets.Method)]
  MethodCacheAttribute = public class(System.Attribute, IMethodImplementationDecorator)
  private
  public
    method HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
  end;

implementation

method MethodCacheAttribute.HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
begin
  // Get a Reference to our Result Value
  var methodResult := new ResultValue();

  // Get a reference to our Static Key Factory.
  var cacheKeyGen := Services.FindType('CirrusCachingAspect.CacheKeyFactory');
  // Generate our cache key from the method name and it's parameters
  var getCacheKey := new AssignmentStatement(new NamedLocalValue('cacheKey'), new ProcValue(new TypeValue(cacheKeyGen), 'GetKeyFromMethod', [aMethod.Name, aMethod.GetParameterArrayValue()]));

  // Get our CacheManager Type and our CacheFactory Type
  var cacheType := Services.FindType('Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager');
  var cacheFactoryType := Services.FindType('Microsoft.Practices.EnterpriseLibrary.Caching.CacheFactory');

  // Get a Reference to our Cache Instance.
  var getCacheInstance := new AssignmentStatement(new NamedLocalValue('methodCache'), new ProcValue(new TypeValue(cacheFactoryType), 'GetCacheManager'));

  // Get data from our cache.
  var getDataFromCache := new ProcValue(new NamedLocalValue('methodCache'), 'GetData', [new NamedLocalValue('cacheKey')]);

  // Cast our result from the Cache to the Result Type.
  var valueCastToResultType := new UnaryValue(new NamedLocalValue('cacheData'), UnaryOperator.Cast, aMethod.Result);

  // Assign the result of our cache request to a local variable.
  var getDataAssignment := new AssignmentStatement(new NamedLocalValue('cacheData'), getDataFromCache);

  // Assign our Cache'd data to the Method Result
  var useCacheData := new AssignmentStatement(methodResult, valueCastToResultType);

  // Add our data to the Cache for next time
  var addDataToCache := new StandAloneStatement(new ProcValue(new NamedLocalValue('methodCache'), 'Add', [new NamedLocalValue('cacheKey'), methodResult]));

  // Key not found in the cache, insert the original body and add a call to the Cache.Add() method.
  var notFoundInCache := new BeginStatement();
  notFoundInCache.Add(new PlaceHolderStatement());
  notFoundInCache.Add(addDataToCache);

  // If found in the cache.
  var ifCacheResult := new IfStatement(new BinaryValue(new NamedLocalValue('cacheData'), new NilValue(), BinaryOperator.Equal), notFoundInCache, useCacheData);

  aMethod.SetBody(Services,
    method begin
      var cacheData: Object;
      var methodCache: CacheManager;
      var cacheKey: String;

      // Get out cache instance
      unquote(getCacheInstance);

      // Generate a key for this method call.
      unquote(getCacheKey);

      // Try to retrieve the data from the cache.
      unquote(getDataAssignment);

      // If data from cache = nil then
      //    call original method
      //    add to cache
      // else
      //    return the data from the cache
      unquote(ifCacheResult);

    end);
end;
</pre>
<p>Which may look quite complex at first but when you look at the actual statements and values being passed around, you can quickly get a feel for how the code works. We can then easily apply this attribute and cache the result of any method in a class automatically like this:</p>
<pre class="brush: delphi;">
type
  Flickr = public class
  private
    _username: string;
  public
    method Flickr(username: String);
    [Aspect:MethodCache]
    method GetPhotos: XmlDocument;
    [Aspect:MethodCache]
    method GetUsername: String;
    [Aspect:MethodCache]
    method GetAuthLevel(user: String): Integer;
  end;
</pre>
<p>Where GetPhotos, GetUsername and GetAuthLevel will all have their results cached automatically by our Aspect. You can see the resulting AOP&#8217;d code disassembled in the reflector below:</p>
<div id="attachment_505" class="wp-caption aligncenter" style="width: 310px"><a href="http://jamiei.com/blog/wp-content/uploads/2009/11/ReflectedMethods-1024x619.png"><img class="size-medium wp-image-505" title="ReflectedMethods" src="http://jamiei.com/blog/wp-content/uploads/2009/11/ReflectedMethods-300x181.png" alt="The RedGate .NET Reflector showing our Cirrus doctored caching code." width="300" height="181" /></a><p class="wp-caption-text">The RedGate .NET Reflector showing our Cirrus doctored caching code.</p></div>
<p>There is still one slight limitation in our method of key generation which is that it will currently only generate a unique key for a method with parameters if the Types of the methods parameters provide a proper implementation of <a href="http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx">ToString()</a> that identifies them. Before you mention it, I had considered using the <a href="http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx">GetHashCode()</a> method for this purpose but the default implementation of the GetHashCode method does not guarantee unique return values for different objects which makes it no more useful than relying on the user to implement the ToString() method.</p>
<p>I have made my implementation available on GitHub as the <a href="http://github.com/jamiei/CirrusCachingAspect">CirrusCachingAttribute</a> where you can feel free to download and play with the source but please note that you will need to <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=1643758B-2986-47F7-B529-3E41584B6CE5&amp;displaylang=en">download and install</a> the Enterprise Library from Microsoft first. I have also added a stub to the Code section on my site for the <a href="http://jamiei.com/blog/code/cirruscachingaspect-for-delphi-prism/">Cirrus Caching Attribute</a>.</p>
<p>There is also a <a href="http://code.remobjects.com/p/prismaspects/">Standard Library of Aspects</a> over on <a href="http://code.remobjects.com">code.remobjects.com</a> which provides a good set of Aspects from which you can learn more about how Cirrus works.</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/MC-4kvsawjE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/11/an-improved-cirrus-caching-aspect/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Time to bury this “Is Delphi Dying” nonsense</title>
		<link>http://jamiei.com/blog/2009/10/time-to-bury-this-is-delphi-dying-nonsense/</link>
		<comments>http://jamiei.com/blog/2009/10/time-to-bury-this-is-delphi-dying-nonsense/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 12:05:45 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Much ado about Nothing]]></category>
		<category><![CDATA[codegear]]></category>
		<category><![CDATA[fun]]></category>
		<category><![CDATA[joke]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=477</guid>
		<description><![CDATA[Every 3-6 months or, more frequently it seems, someone has the urge to post some attention grabbing headline such as &#8220;Is Delphi Dying&#8221; or &#8220;Is Delphi a Dead language?&#8221; (yes, even unintentionally negative headlines hurt). It recently even despicably overflowed onto StackOverflow. Enough is enough, I thought, I am utterly bored with this discussion.
So, I decided to do something [...]]]></description>
			<content:encoded><![CDATA[<p>Every 3-6 months or, more frequently it seems, someone has the urge to post some attention grabbing headline such as &#8220;<a href="http://www.google.co.uk/search?hl=en&amp;rlz=1C1GGLS_en-GBGB331GB331&amp;q=%22Is+delphi+dying%22&amp;btnG=Search&amp;meta=&amp;aq=f&amp;oq=">Is Delphi Dying</a>&#8221; or &#8220;Is Delphi a Dead language?&#8221; (yes, even <a href="http://wings-of-wind.com/2009/10/18/delphi-is-dying-tm/">unintentionally negative</a> headlines hurt). It recently even <a href="http://stackoverflow.com/questions/1584760/what-to-do-when-delphi-dies">despicably</a> overflowed onto StackOverflow. Enough is enough, I thought, I am <strong>utterly bored</strong> with this discussion.<img class="alignright size-medium wp-image-480" title="Google Suggest" src="http://jamiei.com/blog/wp-content/uploads/2009/10/googlesays-300x167.png" alt="Google Suggest" width="300" height="167" /></p>
<p>So, I decided to do something about it. Some of you might have seen some of the marvellous single purpose websites floating around the internet such as:</p>
<ul>
<li><a href="http://letsturnthisfuckingwebsiteyellow.com/">Lets turn this f***ing website yellow</a></li>
<li><a href="http://www.isapplestoredown.com/">Is the Apple Store Down?</a></li>
<li><a href="http://dowebsitesneedtolookexactlythesameineverybrowser.com/">Do websites need to look the same in every browser?</a></li>
<li><a href="http://www.islostarepeat.com/">Is Lost a repeat?</a></li>
<li>and <a href="http://www.yetanotheruselesswebsite.com/">Yet another useless website.</a></li>
</ul>
<p>All are simple, single purpose websites, which generally do <strong>exactly </strong>what they say on the tin (or in the URL as is the case here) and as we know: The information they give must be true after all: &#8220;<em>I read it on the internet, so it must be true&#8221;</em>. So, late last night I got thinking..</p>
<p>May I proudly introduce to you, the Delphi community&#8217;s new and hopefully favourite single serving sites:</p>
<ul>
<li><a href="http://www.isdelphidead.com">www.</a><a href="http://www.isdelphidead.com">isdelphidead</a><a href="http://www.isdelphidead.com">.com</a></li>
<li><a href="http://www.isdelphidying.com">www.isdelphidying.com</a></li>
</ul>
<p>Next time you see someone on a forum, in the newsgroups or on stackoverflow asking the most dull and tedious of all the questions I could possibly hear: <a href="http://www.isdelphidying.com/">Is Delphi Dying?</a> or <a href="http://www.isdelphidead.com/">Is Delphi Dead?</a>,  point them to one of these sites.</p>
<div id="attachment_482" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-482" title="Is Delphi Dying?" src="http://jamiei.com/blog/wp-content/uploads/2009/10/isit-300x174.png" alt="Is Delphi Dead? Is Delphi Dying?" width="300" height="174" /><p class="wp-caption-text">Is Delphi Dead? Is Delphi Dying?</p></div>
<p>I should point out that the people who like to bring up this particular topic are normally quite persistent. In order to dissuade them from rehashing the same <a href="http://wings-of-wind.com/2009/10/18/delphi-is-dying-tm/#comment-1288">tedious</a> and <a href="http://stackoverflow.com/questions/1584760/what-to-do-when-delphi-dies">dull</a> discussions time and time again I have cunningly built in an API.</p>
<p>People who are concerned that that answer might change without them being informed can build an application based on the API which spits out your choice of <a href="http://www.isdelphidying.com/API/?xml">XML</a> or <a href="http://www.isdelphidying.com/API/?json">JSON</a>. This way, the aforementioned doom mongerers can simply build an application (in <a href="http://www.embarcadero.com/products/delphi">Delphi</a>, of course) that sits in their tray and periodically polls the service and reassures those greatly concerned of the answer.</p>
<p>The API is very simple, you merely need to append</p>
<pre class="brush: delphi;">/API</pre>
<p>to the <a href="http://isdelphidead.com">isdelphidead.com</a> or <a href="http://isdelphidying.com">isdelphidying.com</a> domain of your choice and then request either format by querying for XML (default):</p>
<pre class="brush: delphi;">/API?xml</pre>
<p>or JSON:</p>
<pre class="brush: delphi;">/API?json</pre>
<p>It&#8217;s that simple.  So go now and <strong>spread the word</strong> so that the rest of us can carry on in peace.</p>
<p><strong>[Update 01/11/09]:</strong> Russian Delphi programmer <a href="http://www.isdelphidying.narod.ru/">Valerian Kadyshev</a> has posted <a href="http://jamiei.com/blog/2009/10/time-to-bury-this-is-delphi-dying-nonsense/comment-page-1/#comment-595">below</a> to inform us that he has in fact made a tray monitoring application (in Delphi of course!) so that concerned people can download his pre-made one if they don&#8217;t even want to goto the trouble of making it themselves. You can find version 1 of his &#8220;<a href="http://www.isdelphidying.narod.ru/">Is Delphi Dying Monitor</a>&#8221; over on <a href="http://www.isdelphidying.narod.ru/">his site</a>. Marvellous Work Valerian!</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/T18LQ_VQT3Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/10/time-to-bury-this-is-delphi-dying-nonsense/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Dynamically generating code with Delphi Prism</title>
		<link>http://jamiei.com/blog/2009/10/dynamically-generating-code-with-delphi-prism/</link>
		<comments>http://jamiei.com/blog/2009/10/dynamically-generating-code-with-delphi-prism/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 12:21:32 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi Prism]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[delphi prism]]></category>
		<category><![CDATA[introduction]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=458</guid>
		<description><![CDATA[In my last post I covered dynamically compiling code with Delphi Prism and this time I&#8217;m going to introduce dynamically creating code which could then be written out to a source file or compiled from in memory. You might want to generate code dynamically for a wide variety of reasons, whether it be to bootstrap [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post I covered <a href="http://jamiei.com/blog/2009/09/dynamically-compiling-code-with-delphi-prism/">dynamically compiling code with Delphi Prism</a> and this time I&#8217;m going to introduce dynamically creating code which could then be written out to a source file or compiled from in memory. You might want to generate code dynamically for a wide variety of reasons, whether it be to bootstrap a project easily, automatically add some utility code or generate wrapper classes automatically. Dynamically generating code with Delphi Prism is (like almost everything in .NET) no different to the process in which it is done in C# or VB.NET. It is easy to forget that Delphi Prism is fully compatible with the whole of the .NET Framework and this means that you can now safely go back to having the <a href="http://msdn.microsoft.com/en-us/netframework/default.aspx">MSDN Documentation</a> as your best friend.</p>
<p>Before you get too hasty with building your own class generators it&#8217;s also worth noting that Microsoft&#8217;s <a href="http://msdn.microsoft.com/en-us/library/x6c1kb0s.aspx">xsd.exe</a> tool can also be used with Delphi Prism (thanks to <a href="http://wiert.wordpress.com/2009/09/04/net-delphi-prism-how-to-generate-wrapper-classes-code-from-xsd-file/">Jeroen Pluimers</a> and <a href="http://stackoverflow.com/questions/917418/how-to-generate-pascal-code-from-an-xml-schema-in-delphi-prism">Peter Nowotnick</a> for sharing this tip with us).</p>
<h3>Getting Started</h3>
<p>In Order to get started you&#8217;ll need to reference the <strong>RemObjects.Oxygene.CodeModel.dll</strong> and add the CodeDom namespace from this plus System.CodeDom to your uses.</p>
<p>It is worth noting that automated code generation is like our work with the <a href="http://jamiei.com/blog/2009/06/delphi-prism-cirrus-framework/">Delphi Prism AOP Cirrus framework</a> in that the code required to create a small amount of target output code can become quite hard to read at a glance so organise it well.</p>
<p>We&#8217;re going to start off by creating a basic class for Saying Hello (highly innovative you understand! <img src='http://jamiei.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ) and then generating the code and writing it to a new .pas file. Our basic first steps in generating a class involve setting up the unit (with a <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codecompileunit.aspx">CodeCompileUnit</a>), the namespace (with a <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codenamespace.aspx">CodeNamespace</a>) and the class itself (with a <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codetypedeclaration.aspx">CodeTypeDeclaration</a>):</p>
<pre class="brush: delphi;">
namespace CodeDomGeneration;

interface

uses
  System.Linq,
  System.Reflection,
  System.IO,
  System.CodeDom,
  System.CodeDom.Compiler,
  RemObjects.Oxygene.CodeDom;

type
  ConsoleApp = class
  public
    class method Main;
  end;

implementation

class method ConsoleApp.Main;
const
  outputFile = 'uMyClass.pas';
var
  uNewUnit: CodeCompileUnit;
  MyHelloNS: CodeNamespace;
  MyNewClass: CodeTypeDeclaration;
  provider: CodeDomProvider;

begin
  uNewUnit := new CodeCompileUnit;

  MyHelloNS := new CodeNamespace('Hello');
  MyHelloNS.Imports.Add(new CodeNamespaceImport('System'));

  MyNewClass := new CodeTypeDeclaration('TSayHelloClass');
  MyNewClass.IsClass := true;
  MyNewClass.TypeAttributes := TypeAttributes.Public + TypeAttributes.Sealed;
  MyNewClass.Comments.Add(new CodeCommentStatement('This is our CodeDom created class <img src='http://jamiei.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> '));

  MyHelloNS.Types.Add(MyNewClass);
  uNewUnit.Namespaces.Add(MyHelloNS);

  // Get our CodeDomProvider
  provider := CodeDomProvider.CreateProvider('Oxygene');

  // Options.
  var options: CodeGeneratorOptions := new CodeGeneratorOptions();

  // Create our output filestream.
  var sourceWriter: StreamWriter;
  sourceWriter := new StreamWriter(outputFile);

  // Generate our code.
  provider.GenerateCodeFromCompileUnit(uNewUnit, sourceWriter, options);

  // Close our output filestream
  sourceWriter.Close();

  Console.WriteLine('Press Enter to exit..');
  Console.ReadLine;
end;

end.
</pre>
<p>If you run this code, you&#8217;ll find a new <strong>uMyClass.pas</strong> file has been generated in the output directory which contains little more than a class shell and a couple of comments: One to note that the source file was auto-generated by a tool and another to which is our own comment on the TSayHelloClass. You&#8217;ll also note that unlike the previous article, we&#8217;re using:</p>
<pre class="brush: delphi;"> CodeDomProvider.GenerateCodeFromCompileUnit();   </pre>
<p>To <a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider.generatecodefromcompileunit.aspx">Generate code</a> from the Code Document Object Model rather than the <a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider.compileassemblyfromsource.aspx">Compile</a> method we used last time. You could also compile directly from a CodeDom object as alluded to in my previous post on <a href="http://jamiei.com/blog/2009/09/dynamically-compiling-code-with-delphi-prism/">Dynamically compiling Delphi Prism code </a>using the <a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider.compileassemblyfromdom.aspx">CodeDomProvider.CompileAssemblyFromDom method</a>.</p>
<p>The Next step is to add a private field (<a href="http://msdn.microsoft.com/en-us/library/system.codedom.codememberfield.aspx">CodeMemberField</a>) and a public property (<a href="http://msdn.microsoft.com/en-us/library/system.codedom.codememberproperty.aspx">CodeMemberProperty</a>) to our class with its own getter and setter methods:</p>
<pre class="brush: delphi;">
  var MyNameProperty: CodeMemberProperty;
  var MyNameField: CodeMemberField;

 // Add our private field.
  MyNameField := new CodeMemberField;
  MyNameField.Name := 'fFullName';
  MyNameField.Type := new CodeTypeReference('System.String');
  MyNameField.Attributes := MemberAttributes.Private;

  // Add the public property with a Getter and Setter
  MyNameProperty := new CodeMemberProperty;
  MyNameProperty.Name := 'FullName';
  MyNameProperty.Type := new CodeTypeReference('System.String');
  MyNameProperty.Attributes := MemberAttributes.Public;
  MyNameProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), 'fFullName')));
  MyNameProperty.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), 'fFullName'), new CodePropertySetValueReferenceExpression()));

  // Add our two new objects to the parent code tree
  MyNewClass.Members.Add(MyNameField);
  MyNewClass.Members.Add(MyNameProperty);
</pre>
<p> It could very easy to get carried away creating an initialising your new class, methods, fields or properties and forget to .Add() them to the target <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codestatementcollection.aspx">CodeStatementCollection</a> so if your new objects do not show up in the generated code, check that you have actually added them. We can now add a public SayHello method to our class which will greet the previously named entity:</p>
<pre class="brush: delphi;">
  var MySayHello: CodeMemberMethod;

  // Our public method to say &quot;Well Hi there &lt;fFullName&gt;&quot;
  MySayHello := new CodeMemberMethod();
  MySayHello.Name := 'SayHello';
  MySayHello.ReturnType := new CodeTypeReference(typeof(System.String));
  MySayHello.Attributes := MemberAttributes.Public;
  MySayHello.Statements.Add(new CodeMethodReturnStatement(new CodeBinaryOperatorExpression(new CodePrimitiveExpression('Well Hi there '), CodeBinaryOperatorType.Add, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), 'fFullName'))));

  // Add our new method to the parent class.
  MyNewClass.Members.Add(MySayHello);
</pre>
<p>The Method statements that I have added here have been created on the fly and not been structured well for readability at all. As I mentioned at the beginning, you will need to structure your code carefully to ensure readability. If you run this code again now, you should see our SayHello Method as below:</p>
<pre class="brush: delphi;">
method TSayHelloClass.SayHello: System.String;
begin
    exit(('Well Hi there ' + self.fFullName));
end;
</pre>
<p>You can also add statements from &#8220;<em>snippets</em>&#8220;, which allows you to essentially inject code as a string using the <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codesnippetexpression.aspx">CodeSnippetExpression</a> class: </p>
<pre class="brush: delphi;">
  var snippetSayHelloMethod:  CodeSnippetExpression  := new CodeSnippetExpression('Result := Self.fFieldName');
  //Convert the snippets into Expression statements.
  var stmtSayHelloResult: CodeExpressionStatement := new CodeExpressionStatement(snippetSayHelloMethod);
  // Add it to our SayHello Method
  MySayHello.Statements.Add(stmtSayHelloResult);
</pre>
<p><strong>Warning: </strong>Adding method statements from snippets in this manner should be used with great care as you have very little protection against a typo causing a mal-formed code output and I would not recommend generating complex code statements from the <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codesnippetexpression.aspx">CodeSnippetExpression</a>.</p>
<p>There is a Code object representation of anything that you could want to generate, you simply need to find the right class. For example, if we wanted to add a class entry point to our class then we could create one with the <a href="http://msdn.microsoft.com/en-us/library/system.codedom.codeentrypointmethod.aspx">CodeEntryPointMethod</a> class:</p>
<pre class="brush: delphi;">
  var MyMain: CodeEntryPointMethod := new CodeEntryPointMethod();
  MyMain.Name := 'Main';
  MyMain.Attributes := MemberAttributes.Public + MemberAttributes.Static;
  var cs1: CodeMethodInvokeExpression  := new CodeMethodInvokeExpression(
        new CodeTypeReferenceExpression('System.Console'), 'WriteLine',
        new CodePrimitiveExpression('Hello World!') );
  MyMain.Statements.Add(cs1);

  MyNewClass.Members.Add(MyMain);
</pre>
<h3>Conclusion</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/system.codedom.aspx">System.CodeDom</a> space is a very very powerful tool and one that developers used to developing native Win32 Delphi might not be aware of. You will probably be able to dream up of a number of cases where generating some of your Delphi Prism code dynamically could save you time. Use it wisely.</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/XJZTalu7Ct0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/10/dynamically-generating-code-with-delphi-prism/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Dynamically compiling code with Delphi Prism</title>
		<link>http://jamiei.com/blog/2009/09/dynamically-compiling-code-with-delphi-prism/</link>
		<comments>http://jamiei.com/blog/2009/09/dynamically-compiling-code-with-delphi-prism/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 13:13:21 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi Prism]]></category>
		<category><![CDATA[code generation]]></category>
		<category><![CDATA[compilation]]></category>
		<category><![CDATA[delphi prism]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=414</guid>
		<description><![CDATA[Delphi Prism and the .NET Framework are both extremely powerful tools and bring a lot of flexibility that Delphi for Win32 cannot necessarily provide, particularly when it comes to reflection and code generation. I recently started a project where I wanted to be able to compile a string with Delphi Prism code into an assembly without hacking my [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.embarcadero.com/products/delphi-prism">Delphi Prism</a> and the .NET Framework are both extremely powerful tools and bring a lot of flexibility that Delphi for Win32 cannot necessarily provide, particularly when it comes to reflection and code generation. I recently started a project where I wanted to be able to compile a string with Delphi Prism code into an assembly without hacking my way around with the <a href="https://downloads.embarcadero.com/free/delphi_prism">Delphi Prism command line compiler</a>.  This could be used to potentially create a Delphi Prism Snippet Compiler similar to the <a href="http://www.sliver.com/dotnet/SnippetCompiler/">.NET Snippet Compiler</a> from Jeff Key.</p>
<p>It is my intention that this post should introduce you to the process of dynamically compiling code and that the next part will hopefully be an introduction to the process of dynamically generating and compiling code using the .NET CodeDom.</p>
<p>To begin with, create a <strong>New Console Application</strong> in <strong>Delphi Prism</strong> and Add a Reference to the <strong>RemObjects.Oxygene.CodeModel</strong> assembly. For my installation, this was found in the <strong>Bin</strong> directory of the Delphi Prism program files directory.</p>
<p>Once you&#8217;ve done this you can use the following code:</p>
<pre class="brush: delphi;">namespace DynamicCompilation;

interface

uses
  System.Collections,
  System.CodeDom.Compiler,
  RemObjects.Oxygene.CodeDom;

type
  ConsoleApp = class
  public
    class method Main;
  end;

implementation

class method ConsoleApp.Main;
var
  provider: CodeDomProvider;
  strFileOut: string;
  results: CompilerResults;
  cp: CompilerParameters;
  strSource: String;
begin

strSource := &quot;namespace HelloWorld;

interface

type
  ConsoleApp = public class
  public
    class method Main;
  end;

implementation

class method ConsoleApp.Main;
begin
  Console.WriteLine('Hello World.');
end;
end.&quot;;

  // Get our CodeDomProvider
  provider := CodeDomProvider.CreateProvider('Oxygene');

  cp := new System.CodeDom.Compiler.CompilerParameters;
  cp.CompilerOptions := '';
  // Defaults to false which creates a dll instead.
  cp.GenerateExecutable := true;
  strFileOut := 'C:\test.exe';
  cp.OutputAssembly := strFileOut;

  // Compile our code.
  results := provider.CompileAssemblyFromSource(cp, [strSource]);

  Console.WriteLine('Number of Errors Encountered: {0}', results.Errors.Count);
  for error: CompilerError in results.Errors do
      begin
        Console.WriteLine('{0}: {1}', [error.ErrorNumber, error.ErrorText]);
      end;
  if (Assigned(results.PathToAssembly)) then
     begin
       Console.WriteLine('Path to Assembly: {0}', results.PathToAssembly);
     end;

  Console.WriteLine('Press Enter to exit..');
  Console.ReadLine;
end;

end.</pre>
<div id="attachment_424" class="wp-caption aligncenter" style="width: 310px"><a href="http://jamiei.com/blog/wp-content/uploads/2009/09/DynamicCompilation_TestConsoleOutput.png"><img class="size-medium wp-image-424" title="DynamicCompilation_TestConsoleOutput" src="http://jamiei.com/blog/wp-content/uploads/2009/09/DynamicCompilation_TestConsoleOutput-300x151.png" alt="Our Test Console Output" width="300" height="151" /></a><p class="wp-caption-text">Our Test Console Output</p></div>
<p>This code should be fairly straight forward to understand but there are a few parts that are worth drawing attention to. The first is this line:</p>
<pre class="brush: delphi;">provider := CodeDomProvider.CreateProvider('Oxygene');</pre>
<p>I originally tried to create a new instance of the RemObjects.Oxygene.CodeModel.OxygeneCodeProvider as you can when <a href="http://msdn.microsoft.com/en-us/library/bb537926.aspx">creating a CSharpCodeProvider</a>:</p>
<pre class="brush: delphi;">            var provider_options = new Dictionary
                         {
                             {&quot;CompilerVersion&quot;,&quot;v3.5&quot;}
                         };
            var provider = new Microsoft.CSharp.CSharpCodeProvider(provider_options);</pre>
<p>However in my experience calling the constructor on the OxygeneCodeProvider class merely causes a Null Reference Exception when you actually try to use a Compile method on the resulting class. It is worth noting that by replacing the string &#8216;Oxygene&#8217; above with &#8216;VisualBasic&#8217; or &#8216;CSharp&#8217; you can obtain an instance of other language providers.</p>
<p>The next part worth paying careful attention to is the setup of the CompilerParameters:</p>
<pre class="brush: delphi;">  cp := new System.CodeDom.Compiler.CompilerParameters;
  cp.GenerateExecutable := true;
  strFileOut := 'C:\test.exe';
  cp.OutputAssembly := strFileOut;</pre>
<p>This part of the code, configures the Provider to generate an executable instead an assembly (which is the default configuration) and tells the Provider where to output the resulting executable. This should be relatively straightforward and for a full reference of <strong>CompilerParameters</strong> &#8211; see the MSDN documentation on <a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.compilerparameters.aspx">System.CodeDom.Compiler.Compilerparameters</a>.</p>
<p>Those sharp-eyed amongst you may have noticed that the code that I&#8217;m compiling above does not contain any <strong>uses</strong> declarations. First we need to Reference the relevant assemblies using the CompilerParameters.<a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.compilerparameters.referencedassemblies.aspx">ReferencedAssemblies</a> StringCollection:</p>
<pre class="brush: delphi;">  cp := new System.CodeDom.Compiler.CompilerParameters;
  // Clear our Assembly List
  cp.ReferencedAssemblies.Clear;
  // Add a few usual suspects
  cp.ReferencedAssemblies.Add('System.dll');
  cp.ReferencedAssemblies.Add('System.Core.dll');</pre>
<p>You can then &#8220;<strong>uses</strong>&#8221; any namespace in the referenced assemblies (be careful: There is no official .NET assembly called <em>System.Linq.dll</em> for example).</p>
<p>The final part which is worth drawing attention to is the actual compile command:</p>
<pre class="brush: delphi;">   results := provider.CompileAssemblyFromSource(cp, [strSource]);</pre>
<p>For reference, the relevant parts of the declaration for a CodeDomProvider might look something like the following:</p>
<pre class="brush: delphi;">public CodeDomProvider = class abstract(Component)
    public function CompileAssemblyFromDom(options: CompilerParameters; [ParamArray] compilationUnits: CodeCompileUnit[]): CompilerResults; virtual;
    public function CompileAssemblyFromFile(options: CompilerParameters; [ParamArray] fileNames: string[]): CompilerResults; virtual;
    public function CompileAssemblyFromSource(options: CompilerParameters; [ParamArray] sources: string[]): CompilerResults; virtual;</pre>
<p>You can feed the CompileAssemblyFrom methods several different files, strings, or Dom structures which might represent different .pas files that you would create when you created a project in Delphi Prism. The example below includes an additional class:</p>
<pre class="brush: delphi; collapse: true; light: false; toolbar: true;">namespace DynamicCompilation;

interface

uses
  System.Collections,
  System.CodeDom.Compiler,
  RemObjects.Oxygene.CodeDom;

type
  ConsoleApp = class
  public
    class method Main;
  end;

implementation

class method ConsoleApp.Main;
var
  provider: CodeDomProvider;
  strFileOut: string;
  results: CompilerResults;
  cp: CompilerParameters;
  strSource: String;
begin

strSource := &quot;namespace HelloWorld;

interface

type
  ConsoleApp = public class
  public
    class method Main;
  end;

implementation

class method ConsoleApp.Main;
var
  PingPong: TPingPong;
begin
  PingPong := new TPingPong;
  Console.WriteLine(PingPong.Ping);
  Console.WriteLine('Hello World.');
end;
end.&quot;;

var strSource2 := &quot;namespace HelloWorld;

interface

type
  TPingPong = public class
  public
    method Ping: string;
  end;

implementation

method TPingPong.Ping: string;
begin
  Result := 'PONG!';
end;
end.&quot;;

  // Get our CodeDomProvider
  provider := CodeDomProvider.CreateProvider('Oxygene');

  cp := new System.CodeDom.Compiler.CompilerParameters;

  cp.CompilerOptions := '';
  // Defaults to false which creates a dll instead.
  cp.GenerateExecutable := true;
  strFileOut := 'C:\test.exe';
  cp.OutputAssembly := strFileOut;

  // Clear our Assembly List
  cp.ReferencedAssemblies.Clear;
  // Add a few usual suspects
  cp.ReferencedAssemblies.Add('System.dll');
  cp.ReferencedAssemblies.Add('System.Data.dll');

  // Compile our code.
  results := provider.CompileAssemblyFromSource(cp, [strSource2, strSource]);

  //Console.WriteLine('Generated assembly name: ' + results.CompiledAssembly.FullName);
  Console.WriteLine('Number of Errors Encountered: {0}', results.Errors.Count);
  for error: CompilerError in results.Errors do
      begin
        Console.WriteLine('{0}: {1}', [error.ErrorNumber, error.ErrorText]);
      end;
  if (Assigned(results.PathToAssembly)) then
     begin
       Console.WriteLine('Path to Assembly: {0}', results.PathToAssembly);
     end;

  Console.WriteLine('Press Enter to exit..');
  Console.ReadLine;
end;

end.</pre>
<p>And voila.. the output from our dynamically compiled executable can be seen as below:</p>
<div id="attachment_425" class="wp-caption aligncenter" style="width: 310px"><a href="http://jamiei.com/blog/wp-content/uploads/2009/09/DynamicCompilation_ExecutableOutput.png"><img class="size-medium wp-image-425" title="DynamicCompilation_ExecutableOutput" src="http://jamiei.com/blog/wp-content/uploads/2009/09/DynamicCompilation_ExecutableOutput-300x151.png" alt="The output from our dynamically generated executable" width="300" height="151" /></a><p class="wp-caption-text">The output from our dynamically generated executable</p></div>
<p>If the other compiler methods available with our CodeProvider caught your eye then this leads me nicely onto my intended next steps. While generating code from a string containing your code is nice and easy, sometimes it may not be the best way to approach Code Generation. </p>
<p>I realise that the end result of the above could have been achieved by simply writing a file out and then executing the command line compiler but where&#8217;s the fun in that? Next time I intend on looking at generating a CodeDom tree and providing this to the Compiler (no more potentially troublesome string manipulation required).</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/8aR9U_Yz8dw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/09/dynamically-compiling-code-with-delphi-prism/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Malware specifically targeting Delphi</title>
		<link>http://jamiei.com/blog/2009/08/malware-specifically-targeting-delphi/</link>
		<comments>http://jamiei.com/blog/2009/08/malware-specifically-targeting-delphi/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 13:09:22 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[compiler]]></category>
		<category><![CDATA[malware]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=404</guid>
		<description><![CDATA[The F-Secure blog has details of a Malware variant that they&#8217;ve found that solely targets installed Delphi versions 4 -7. F-Secure currently detect this as: Virus.Win32.Induc.a. The malware saves a clean copy of SysConsts.dcu and then adds a call to its own init function at the entrypoint of the SysConsts.dcu library. The malware is rather [...]]]></description>
			<content:encoded><![CDATA[<p>The F-Secure blog has details of a Malware variant that they&#8217;ve found that solely targets installed Delphi versions 4 -7. F-Secure currently detect this as: <em>Virus.Win32.Induc.a</em>. The malware saves a clean copy of <strong>SysConsts.dcu</strong> and then adds a call to its own init function at the entrypoint of the <strong>SysConsts.dcu library</strong>. The malware is rather limited in its viability because it seems to be limited to infecting <strong>Delphi Versions 4-7</strong> and the code that it inserts into SysConsts.dcu apparently seems to do little more than reinfecting Delphi with itself so it&#8217;s not potentially that damaging.</p>
<p>I would probably describe it more as a nuisance than malicious because of it&#8217;s limited payload but worth keeping an eye on. I wonder about the motives of it&#8217;s author.</p>
<p>For full details see the F-Secure blog post titled <a href="http://www.f-secure.com/weblog/archives/00001752.html">0wn1ng Delphi</a>.</p>
<p>Now to me, if you&#8217;re still using Delphi versions 4-7 then you can now promptly rush into your Boss&#8217;s office and use that magic word: &#8220;security&#8221; as an excuse to get approved budget to upgrade yourself to the upcoming <a href="http://etnaweb04.embarcadero.com/rad-studio-2010/">Delphi 2010</a>, which looks to contain a whole bunch of fantastic features and upgrades.</p>
<p>[<strong>Update:</strong> Apparently the problem was initially discovered by the Russian programmer who runs the Russian Language Gunsmoker blog.]</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/vXgMXKNecto" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/08/malware-specifically-targeting-delphi/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>The Delphi Community: From the Outside</title>
		<link>http://jamiei.com/blog/2009/07/the-delphi-community-from-the-outside/</link>
		<comments>http://jamiei.com/blog/2009/07/the-delphi-community-from-the-outside/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 17:55:13 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[codegear]]></category>
		<category><![CDATA[language choices]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=362</guid>
		<description><![CDATA[Someone on Twitter recently pointed me to LangPop.com &#8211; which claims to gather together data to give you an estimated rating of how popular certain Programming languages are. I know that most people have seen the TIOBE Programming Community index at some point which uses similar data mining methods to LangPop. This is the first [...]]]></description>
			<content:encoded><![CDATA[<p>Someone on Twitter recently pointed me to <a href="http://langpop.com/">LangPop.com</a> &#8211; which claims to gather together data to give you an estimated rating of how popular certain Programming languages are. I know that most people have seen the <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">TIOBE Programming Community index</a> at some point which uses similar data mining methods to LangPop. This is the first chart which uses a similar data method to the TIOBE index which uses a very broad search engine ranking:</p>
<div id="attachment_369" class="wp-caption aligncenter" style="width: 558px"><a href="http://langpop.com/"><img class="size-full wp-image-369 " title="Yahoo Search Results" src="http://jamiei.com/blog/wp-content/uploads/2009/07/yahoo_lang_results.png" alt="LangPop.com - Yahoo Search Results - Searches took the form &quot;language programming&quot;" width="548" height="364" /></a><p class="wp-caption-text">LangPop.com - Yahoo Search Results - Searches took the form &quot;language programming&quot;</p></div>
<p>What is different about <a href="http://langpop.com">LangPop</a>, however, is the other graphs that it presents later on which searches different data sources and tries to present different angles of a particular programming language community. For those who like their summaries like an icicle, cold and to the point: Delphi doesn&#8217;t appear to pull the weight we owe it in certain areas.</p>
<h3>What does this all mean?</h3>
<p><strong>Absolutely Nothing</strong> much but also something.</p>
<h3>Absolutely Nothing Much?</h3>
<p>This is <strong>not a popularity contest</strong>, nor should it be. Critics of the data sampling methods used in on LangPop and the TIOBE index can argue that they are inaccurate, flawed, biased and any number of other ways of describing why the data should not be relied upon. In the end, the business case for the language used in your projects can only be considered <strong>by you</strong> based on a huge number of project specific factors and whilst this chart can hint at an economic condition it can also be argued to be a fairly superficial reason amongst others. These charts didn&#8217;t change the way I saw any one particular language.</p>
<h3>But also something?</h3>
<p>What interested me about this particular page wasn&#8217;t where Delphi was ranked in comparison to other languages but where it ranked in comparison to itself when compared to the other sources of data. By looking at Data sources where Delphi programming has slid a long way down or up when compared with the nominal position that both <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">TIOBE</a> and the initial chart on <a href="http://LangPop.com">LangPop.com</a> (<strong>Roughly 11th</strong>) we can see where the Delphi is <em>lacking</em> in the eyes of an outsider who has no experience with the Delphi community.</p>
<p>This means that we can effectively see in what areas Delphi maintains a low profile (and can be improved). These are the areas where maybe with some improvement we could begin to l<em>ure new programmers</em>, <em>fresh blood</em> and begin to <em>change the perception of Delphi</em>. Lets look at the other data sources presented in these charts:</p>
<p><strong>Craigslist: </strong>Used to search for job availability specifying a certain language. Arguments aside over Craigslist not being representative of the job market. At least it&#8217;s occasionally used to post some <a href="http://sfbay.craigslist.org/sfc/eng/1246353621.html">seriously funny job listings</a>. Delphi produces a disappointing score on this test and slips below Assembly, Shell Scripting and Cobol. There must be better data on the number of Delphi jobs out there so I&#8217;m not too focussed on this.</p>
<p><em><span style="color: #ff0000;">Slips -7 places.</span></em></p>
<p><strong>Amazon:</strong> Used to assess the number of books written about a particular language. Delphi appears to have relatively few books, especially when compared to languages that are both younger and older, languages that jump up the list here include Fortran, Cobol and Ada. As anecdotal backup for this: the number of Delphi books released each year in the past 10 years seems to be in decline.</p>
<p><span style="color: #ff0000;"><em>Slips -7 places.</em></span></p>
<p><strong>Google Code &amp; Freshmeat: </strong>Used to assess the volume of Open Source projects created with a language. Before this I had a mis-guided impression that there was a relatively small number open source projects using Delphi but on Google Code Delphi actually holds it&#8217;s own nicely. I attribute the slip in its form on the Freshmeat comparison because Freshmeat <a href="http://freshmeat.net/about">declares itself</a> to be an index of Unix and cross-platform software (which Delphi isn&#8217;t really cut out for just yet &#8211; but will be).</p>
<p><span style="color: #ff0000;"><em>Equal &amp; Slips -7 places respectively.</em></span></p>
<p><strong>Del.icio.us: </strong>Gives us an indicator of what programmers are bookmarking and therefore indicates a rough measure of how interesting and &#8220;desirable&#8221; a language is. This is where the table of results differed most from the index <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">TIOBE results</a>. Delphi programmers are clearly not adopting social-bookmarking tools because this is we see that the number of Delphi bookmarks is disappointingly low (I&#8217;m doing <a href="http://delicious.com/jamiei">my part</a>, fwiw). You can&#8217;t read too much into this measurement except that it also indicates that not many people outside the Delphi community bookmark &amp; tag delphi links (whereas many up and coming languages are researched by people wanting to learn it).</p>
<p><span style="color: #ff0000;"><em>Slips 10 places.</em></span></p>
<p><strong>Ohloh:</strong> <a href="http://www.ohloh.net/">Olhloh</a> provides information and statistics about various open source projects and the developers that contribute to them. On Ohloh Delphi appears to be underrepresented and it is here that Olhloh actually measures more registered developers contributing to Pascal Projects (such as <a href="http://www.ohloh.net/p/lazarus">Lazarus</a> and <a href="http://www.ohloh.net/p/3311">fpc</a>) than Delphi developers. This doesn&#8217;t necessarily mean that there are more pure Pascal developers than Delphi developers but that there are more Pascal developers contributing to large open source projects.</p>
<p><span style="color: #ff0000;"><em>Slips 7 places.</em></span></p>
<p>There are also other measurements such as the number of times it is mentioned on <a href="http://langpop.com/#reddit">programming.reddit.com</a> and <a href="http://langpop.com/#slashdot">Slashdot</a> where it represents <strong>almost a zero presence</strong> in the selection of languages that they&#8217;ve chosen to sample.</p>
<div id="attachment_387" class="wp-caption aligncenter" style="width: 554px"><a href="http://langpop.com"><img class="size-full wp-image-387 " title="Sample from programming.reddit.com" src="http://jamiei.com/blog/wp-content/uploads/2009/07/reddit.png" alt="LangPop.com - programming.reddit.com Results" width="544" height="362" /></a><p class="wp-caption-text">LangPop.com - programming.reddit.com Results</p></div>
<p>This might be linked to the same reason why it doesn&#8217;t rank highly in the <a href="http://langpop.com/#delicious">del.icio.us index</a> either. Delphi also appears to be under represented in the <a href="http://langpop.com/#irc">FreeNode IRC network chart</a> as well being pitifully under represented in the &#8220;<a href="http://langpop.com/#normalizeddiscussion">Normalized Discussion Site</a>&#8221; results (although it&#8217;s interesting to note that they don&#8217;t mention which discussion sites they monitor). IRC use in general could be considered to have experienced better days but I have spent a lot of time helping in the #delphi room of a  <a href="http://irc.netsplit.de/networks/top100.php">Top 5 IRC network</a> and would always love to see more people sharing and helping others.</p>
<p><em>[<strong>Updated 9th July: </strong>Dave Welton from LangPop.com has since notified me in <a href="http://jamiei.com/blog/2009/07/the-delphi-community-from-the-outside/#comment-447">a comment below</a> that the Normalised Discussion Site results are a combination of the section with  programming.reddit.com and slashdot etc. My fault!]</em></p>
<h3>Should we be concerned?</h3>
<p>No. There are good reasons why some of these measurements do not accurately represent the picture that they claim to portray. It does give us food for thought because this represents how outsiders see the Delphi community and the Delphi Language as a whole. It is interesting though, why do we have an apparent shortage of Delphi Programming books being published? Although some authors are still producing excellent books (such as the <a href="http://www.marcocantu.com/dh2009/">Delphi 2009 HandBook</a> by <a href="http://www.marcocantu.com/">Marco Cantu</a> which you can currently get for free if you buy or <a href="http://www.embarcadero.com/rad2009promo-delphibook/">try Delphi 2009</a>) there does appear to be a very small number published in the last few years. I&#8217;m not sure why this is, I&#8217;ve always thought that there is certainly room for a several books on Delphi 2009, Delphi Prism and I personally would like to see a book solely on recipes for <a href="http://jamiei.com/blog/2009/06/delphi-prism-cirrus-framework/">Delphi Prism Cirrus Aspects</a>.</p>
<p>What of the open source projects? As a commercial tool Delphi isn&#8217;t a terribly good offering for open source projects at present which might explain why it doesn&#8217;t feature that strongly in Open source offerings. I&#8217;ve <a href="http://jamiei.com/blog/2009/02/turbo-delphi-an-open-letter/">long campaigned</a> for a renewed focus on the <a href="http://jamiei.com/blog/2009/02/turbo-delphi-an-open-letter/">Turbo Delphi</a>&#8217;s or Delphi Personal editions for exactly this reason.</p>
<p>I did find it interesting that as a community we seem to be quite bad at making &#8220;noise&#8221; in bookmarking sites, programming news sites and discussion boards leading those outside the community to believe that Delphi Developers are fewer in numbers than they actually are. Some may scorn these as useless activities however I do feel that general publicity, interesting news, projects and cool links do have a huge impact on how outsiders view a language community. I do also feel that the planned releases of Delphi containing Cross platform Delphi and 64 Bit Delphi will pull Delphi back up on these metrics as it begins to be used in new and interesting ways.  I&#8217;m not sure if it&#8217;s just me but I have noticed a renewed vigour in the Delphi community of late.</p>
<h3>What now?</h3>
<p>Personally, I feel that the Delphi Community is beginning the fight back, with more high profile projects, more unusual projects and fresh users are increasingly <a href="http://delphi.wikia.com/wiki/The_Business_Case_For_Delphi">making the case for Delphi</a> (and we&#8217;re also seeing some great evangelism posts from <a href="http://compaspascal.blogspot.com/2009/06/delphi-is-fast-very-fast.html">within the community</a>, not to mention great new initiatives like <a href="http://www.delphi.org">Delphi Podcasts</a>). The kind of community growth that will highlight delphi to an outsider can only be built organically with hard work and we can take small steps to begin on that path. Delphi itself is also in great hands, it seems to me to be going from strength to strength since CodeGear splitting away from a certain troubled parent company that rhymes with <a href="http://www.borland.com">Morland</a>. Think about this: In the last 12 months we&#8217;ve seen significantly revived confidence in the community, A superb .NET offering with <a href="http://www.embarcadero.com/products/delphi_prism/">Delphi Prism</a> and news of a renewed attack force with <a href="http://www.theregister.co.uk/2009/06/12/embarcadero_codegear_tools_future/">Cross Platform Delphi</a> and <a href="http://blog.marcocantu.com/blog/my_take_new_delphi_roadmap.html">64-Bit Delphi applications</a> for extra-strength apps.</p>
<p>What do you think of my reaction to these graphs? What other ways can we, the community, evangelise Delphi and change an unfamiliar programmers perspective of Delphi and the Delphi Community? What makes you excited about a particular language? (in both a professional and a personal setting)</p>
<p>And to pre-empt the inevitable naysayers out there: Delphi is neither dead nor dying.</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/pctmXSRJdXM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/07/the-delphi-community-from-the-outside/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Delphi Prism and the Cirrus Framework</title>
		<link>http://jamiei.com/blog/2009/06/delphi-prism-cirrus-framework/</link>
		<comments>http://jamiei.com/blog/2009/06/delphi-prism-cirrus-framework/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 08:10:48 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi Prism]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[aop]]></category>
		<category><![CDATA[cirrus]]></category>
		<category><![CDATA[delphi prism]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=337</guid>
		<description><![CDATA[The May 2009 Release of Delphi Prism introduced the Cirrus layer that provides Delphi Prism developers access to a library for Aspect Oriented Programming natively for the first time. The AOP Wikipedia article has a much more detailed explaination than I could provide but for those who don&#8217;t want to read the full article AOP [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://edn.embarcadero.com/article/39578">May 2009 Release</a> of Delphi Prism introduced the <a href="http://prismwiki.codegear.com/en/Cirrus">Cirrus</a> layer that provides Delphi Prism developers access to a library for <a href="http://en.wikipedia.org/wiki/Aspect_Oriented_Programming">Aspect Oriented Programming</a> natively for the first time. The <a href="http://en.wikipedia.org/wiki/Aspect_Oriented_Programming">AOP Wikipedia</a> article has a much more detailed explaination than I could provide but for those who don&#8217;t want to read the full article AOP represents a new programming paradigm which claims to allow a cleaner separation of concerns. The general idea is that you can write your code as an <em>Aspect</em> which can then be injected into your target class, allowing the <em>Aspec</em>t code to replace, wrap or alter the target code. There are a few 3rd party frameworks for Delphi Win32 such as <a href="http://code.google.com/p/meaop/">MeAOP</a> but I&#8217;m not sure if their support is anything like as extensive as Cirrus.</p>
<h4>Why would you need  to use AOP?</h4>
<p>Many people don&#8217;t really understand why they would need to use AOP in any way. It&#8217;s true that nearly all programming paradigms support some form of separation and modularity but to see where this can quickly fall down, you simply have to look at the classic <a href="http://prismwiki.codegear.com/en/Cirrus_Introduction">logging example</a> which has been the staple diet of coverage of the <a href="http://prismwiki.codegear.com/en/Cirrus">Cirrus framework</a>. Logging is a good example because it is likely that if your application implements logging features, then you probably have logging code mixed up in your beautifully designed business objects at various places tainting the implementation of your once clean object.</p>
<h4>A Simple Example</h4>
<p>For the purposes of those people who weren&#8217;t convinced on it&#8217;s usefulness from the example given. Imagine we have a very important Business object of a Type called <strong>TCustomer</strong>. We&#8217;ve been told that we need to log everything done to our Customer objects for audit purposes (and you wouldn&#8217;t want to get on the wrong side of the Internal Audit team..).  We could easily add our logging calls into every function of TCustomer but this going to require a lot of <em>CTRL+C</em>, <em>CTRL+V</em> and is a lot of identical code-repetition and shouldn&#8217;t we be striving to avoid code repetition? This might also get your local overly-sensitive <a href="http://www.secretgeek.net/copy_paste_dont_do_it.asp">Anti Copy-Paste mafia</a> up in arms. There is another problem with simply inserting our code into each method: What happens if later on, another programmer adds another method for updating, deleting or even just saving a copy of our Customer. Internal Audit are not going to be happy. Of course, you could blame it on your inexperienced colleague but that&#8217;s not going to make much difference, it&#8217;s a team failure after all.</p>
<p>Had we used AOP we could have used something as simple as the <a href="http://prismwiki.codegear.com/en/Cirrus_Introduction">Cirrus Introduction</a> LogToMethod code, tagged our <strong>TCustomer</strong> class with a single attribute and been saved from this potential oversight:</p>
<pre class="brush: delphi;">// For the full code for this example, please see the original introductory tutorial at:
// http://prismwiki.codegear.com/en/Cirrus_Introduction
namespace MyLogToMethodAspect;

interface
uses
  RemObjects.Oxygene.Cirrus;

type
  [AttributeUsage(AttributeTargets.Class or AttributeTargets.Struct)]
  LogToMethodAttribute = public class(System.Attribute, IMethodImplementationDecorator)
  public
    [Aspect:AutoInjectIntoTarget]
    class method LogMessage(aEnter: Boolean; aName: String; Args: Array of object);

    method HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
  end;

implementation

class method LogToMethodAttribute.LogMessage(aEnter: Boolean; aName: String;
  Args: Array of object);
begin
  if aEnter then
    Console.WriteLine('Entering ' + aName)
  else
    Console.WriteLine('Exiting ' + aName);
end;

method LogToMethodAttribute.HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
begin
  if String.Equals(aMethod.Name, 'LogMessage',
    StringComparison.OrdinalIgnoreCase) then exit;
  if String.Equals(aMethod.Name, '.ctor',
    StringComparison.OrdinalIgnoreCase) then exit;

  // Cool use of anonymous methods here....
  aMethod.SetBody(Services,
    method begin
      LogMessage(true, Aspects.MethodName, Aspects.GetParameters);
      try
        Aspects.OriginalBody;
      finally
        LogMessage(false, Aspects.MethodName, Aspects.GetParameters);
      end;
    end);
end;

end.</pre>
<p>Of course, you don&#8217;t <strong>need</strong> Aspect Oriented Programming in the same way as you don&#8217;t <strong>need</strong> Object Oriented Programming, we could just revert to procedural programming but as programmers we strive to separate various concerns cleanly and this is another step towards that.</p>
<h4>What&#8217;s the catch?</h4>
<p>The problem with separating our code in such a way is that potentially, it could be hard for a programmer unfamiliar with AOP to understand the code as the only clue of any logging activity for our target class might be a single attribute in our interface section. Our Aspect might also rely upon the underlying method in which case we could run into problems if we restructure or  move our methods around causing unintended consequences. There is also a concern that a serious bug in our Aspect code could lead to a more widespread failure in the program (as it has the potential to be applied to large swathes of code easily).</p>
<p>However, with careful testing and implementation these potential drawbacks can be mitigated.</p>
<h4>Apart from Logging, what else can I use it for?</h4>
<p>Typical uses include logging, authentication, caching and dependency injection. <a href="http://blog.moshine.com/blog/Default.aspx">John Moshakis</a> has been blogging some elegant real-life uses of the Cirrus framework such as <a href="http://blog.moshine.com/blog/post/2009/05/Implementing-Dependency-Injection-using-AOP.aspx">Implementing Dependency Injection</a>, allowing him to switch seamlessly between test and production services in an app.</p>
<h4>My Own Journey to AOP</h4>
<p>After the Cirrus Framework was released I wanted to try to build my own Aspect which wasn&#8217;t the logging sample provided. I had a service that retrieved a string of XML from a REST Web Service at frequent intervals which I felt could be improved with caching functionality. The Code for the Web Service and for the Cache were just test classes for the purpose of this experiment but I would imagine that you could extend this to use the <a href="http://msdn.microsoft.com/en-us/library/dd203226.aspx">The Caching Application Block</a> from the <a href="http://msdn.microsoft.com/en-us/library/dd203099.aspx">Microsoft Enterprise Library</a> if you wished. Normally, I could add caching to each method by modifying it like so:</p>
<pre class="brush: delphi;">method TFlickr.GetUserInformation(username: String): String;
begin
  // Do we have this information in our cache?
  if (MyCache.HasData('UserInfo_' + username)) then
  begin
    // We do, use the cache'd data.
    Result := MyCache.GetData('UserInfo_' + username);
  end
  else
  begin
    // No cache'd version, retrieve a new set of data.
    { Open our TCP Socket, call the webservice with the
      correct parameters and return the result.     }
    // Add our newly retrieved data to the cache.
    MyCache.SetData('UserInfo_' + username, Result);
  end;
end;</pre>
<p>This method of implementation would lead to me having to put this code into each method and would lead to code repetition and possibly bugs being introduced (for example, if I forgot to update the cache key string on one method). I wondered if I could have a CacheString attribute that would allow me to automaticaly add my generic &#8220;do we have cache&#8217;d data? if so use it else carry on&#8221;  code to each method.</p>
<p>First of all, I tried essentially moving this code into a Method Aspect and adding a generic key function which takes the method name and method arguements and turns it into a consistent string using the Aspects.MethodName and Aspects.GetParameters methods:</p>
<p><span style="color: #ff0000;"><strong>WARNING! BROKEN CODE:</strong></span></p>
<pre class="brush: delphi;">class method MyCache.getKeyFromMethod(aName: String; Args: Array of object): String;
begin
  var argConcat: String;

  argConcat := aName;
  for argTemp: String in Args do
  begin
    argConcat := argConcat + argTemp;
  end;

  Result := argConcat;
end;

method MyCacheAttribute.HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
begin
  aMethod.SetBody(Services,
    method begin
	  var cacheKey := MyCache.getKeyFromMethod(Aspects.MethodName, Aspects.GetParameters);
	  // Do we have this information in our cache?
	  if (MyCache.HasData(cacheKey)) then
	  begin
		// We do, use the cache'd data.
		Result := MyCache.GetData(cacheKey);
	  end
	  else
	  begin
        Aspects.OriginalBody;

        // Send the result of the Original Method to the Cache for next time.
        MyCache.setData(cacheKey, Result);
      end;
    end);
end;</pre>
<p>Unfortunately it is not quite as simple as just placing your code into the AMethod.SetBody Anonymous method. Luckily it turned out that the <a href="http://prismwiki.codegear.com/en/Cirrus">Cirrus documentation</a> on the Wiki had recently been updated and I discovered the <a href="http://prismwiki.codegear.com/en/Cirrus_Statements_Namespace">Cirrus Statements</a> and <a href="http://prismwiki.codegear.com/en/Cirrus_Values_Namespace">Cirrus Values</a> namespaces after a bit of helpful guidance from <a href="http://twitter.com/moshakis">John Moshakis</a> on StackOverflow and Twitter (thank-you for that John!). I discovered that what you are required to do in most cases is to construct your code in an almost compiler like fashion using the Statement and Values namespaces.</p>
<p>Eventually after playing around with the Cirrus API, I eventually ended up with the following code:</p>
<pre class="brush: delphi;">
method MemCacheAttribute.HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
begin
  // Get a Reference to our Result Value
  var newResult := new ResultValue();

  // Get our MemCache Object
  var cacheType := Services.FindType('AOPCacheLibrary.MyCache');
  // Setup our static methods.
  var getDataProc := new ProcValue(new TypeValue(cacheType), 'getData', [new NamedLocalValue('cacheKey')]);

  // Assign the result of our cache request to a local variable.
  var getDataAssignment := new AssignmentStatement(new NamedLocalValue('strData'), getDataProc);

  // CACHE DATA USED: To assign our Cache'd data to the Method Result
  var useCacheData := new AssignmentStatement(newResult, new NamedLocalValue('strData'));
  // CACHE DATA NOT USED: To assign the result of our OriginalBody to the Method Result.
  var useOriginalMethodResult := new AssignmentStatement(new NamedLocalValue('resultOriginal'), newResult);

  aMethod.SetBody(Services,
    method begin
      var strData: String;
      // Get our Cache Key Name
      var cacheKey := MyCache.getKeyFromMethod(Aspects.MethodName, Aspects.GetParameters);

      try
        // See if we have anything in the cache for this key.
        unquote(getDataAssignment);
        // Replace this
        unquote(useCacheData);
      except
        on E: Exception do
        begin
          var resultOriginal: String;
          // No cache data found, execute the original method body.
          Aspects.OriginalBody;

          // Assign the result of the Original Method to a new variable.
          unquote(useOriginalMethodResult);
          // Send the result of the Original Method to the Cache for next time.
          MyCache.setData(cacheKey, resultOriginal);
        end;
      end;
    end);
end;</pre>
<p>According to the <a href="http://www.red-gate.com/products/reflector/">Red Gate .NET Reflector</a> and Disassembler, this produces the following code:</p>
<pre class="brush: delphi;">
    function TFlickr.GetUserInformation(username: String): String;
    var
        Result: string;
    begin
        cacheKey := MyCache.getKeyFromMethod('GetUserInformation', New(array[1] of TObject, ( ( userid ) )));
        try
            Result := MyCache.getData(cacheKey)
        except
            on E: Exception do
            begin
                // This is where we do our _ORIGINAL_ function
                resultOriginal := Result;
                MyCache.setData(cacheKey, resultOriginal)
            end
        end;
        begin
            Result := Result;
            exit
        end
    end;</pre>
<p>This means that I can now add caching to any of my string returning web service methods in my class by simply tagging the methods that I want cached with a code attribute:</p>
<pre class="brush: delphi;">
  TFlickr = public class
  private
	{code}
  public
    {more code etc, etc}
    [Aspect:MyStringCache]
    method TFlickr.GetUserInformation(username: String): String;
  end;
</pre>
<p>This works perfectly but there are a few problems with this code:</p>
<ul>
<li>As you can see: constructing statements using the Cirrus API (in the statements before the aMethod.setBody) doesn&#8217;t exactly make for readable code. You may wish to consider outlining each statement with <a href="http://en.wikipedia.org/wiki/Pseudocode">psuedocode</a> so that it is clearer at a glance what the API calls produce.</li>
<li>I should be using the <a href="http://prismwiki.codegear.com/en/ProcValue_Class">Cirrus Procedure Value</a> calls for all three calls to the Static &#8220;MyCache&#8221; class but am not because I couldn&#8217;t quite get this working. Please be aware that John informs me that the method I use in the first and third instance is <strong>not</strong> the correct way to go about this.</li>
<li>This exact method only currently works for System.String returning methods. There must be a way of abstracting this function to apply it to almost a method returning almost any type (if anyone has any suggestions about how this might be accomplished then, by all means post a link in the comments).</li>
</ul>
<p>Please note that the code above is <strong>NOT</strong> intended to be a reference implementation for AOP or Application Caching but is merely intended to show you my own learning path with Cirrus and AOP. The Cirrus API is quite difficult to work with at first and can give you frustrating compiler errors but it&#8217;s worth keeping an eye on the <a href="http://prismwiki.codegear.com/en/Cirrus">documentation</a> pages and as more examples appear online it will become easier to work with. You should have the <a href="http://www.red-gate.com/products/reflector/">Red Gate .NET Reflector</a> on hand with its disassemble function to confirm exactly what the resulting code in your Output assemblies looks like.</p>
<p>If you have any constructive suggestions for my code above then please let me know. Additionally, if you think it would be useful for me to post the downloadable Delphi Prism project then please also let me know in the comments below.</p>
<h4>Starting your own journey to Cirrus/AOP</h4>
<ul>
<li><a href="http://prismwiki.codegear.com/en/Cirrus">Delphi Prism Wiki &#8211; Cirrus Documentation</a> &#8211; The Definitive Reference.</li>
<li><a href="http://it-republik.de/konferenzen/delphi_live/material/DelphiLive2009_mckeeth_aspect_oriented_programming.zip">Jim McKeeth&#8217;s DelphiLive! Presentation on AOP</a> &#8211; A Good Introduction and Overview to AOP.</li>
<li><a href="http://prismwiki.codegear.com/en/Cirrus_Introduction">Delphi Prism Wiki &#8211; Cirrus Introduction</a> &#8211; An Introductory guide to Cirrus and AOP that will guide you into building the logging example shown in this post.</li>
<li><a href="http://blog.moshine.com/blog/Default.aspx">John Moshakis&#8217;s Blog </a>- Some Excellent Examples of real applications of the Cirrus Framework.</li>
</ul>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/5BMZ6m97n38" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/06/delphi-prism-cirrus-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Turbo Delphi: A Hidden gem in DelphiLive?</title>
		<link>http://jamiei.com/blog/2009/05/turbo-delphi-a-hidden-gem-in-delphilive/</link>
		<comments>http://jamiei.com/blog/2009/05/turbo-delphi-a-hidden-gem-in-delphilive/#comments</comments>
		<pubDate>Thu, 21 May 2009 10:54:30 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[apps-i-love]]></category>
		<category><![CDATA[codegear]]></category>
		<category><![CDATA[hobbyist]]></category>
		<category><![CDATA[turbos]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=314</guid>
		<description><![CDATA[I enjoyed the Twitter live-coverage and exciting revelations of DelphiLive! particularly from JimMcKeeth and marcocantu but also many others. Despite the surprise revelations of Project X etc a particular slide caught my eye amongst the many others:

Did you see it? ..ISVs, VARs, Consultants and Hobbyists.. I jumped at the phrase and asked Jim whether any [...]]]></description>
			<content:encoded><![CDATA[<p>I enjoyed the Twitter live-coverage and <a href="http://blogs.embarcadero.com/abauer/2009/05/20/38885">exciting revelations</a> of <a href="http://www.delphilive.com/">DelphiLive!</a> particularly from <a href="http://twitter.com/JimMcKeeth">JimMcKeeth</a> and <a href="http://twitter.com/marcocantu">marcocantu</a> but also <a href="http://search.twitter.com/search?q=&amp;ands=%23delphilive&amp;phrase=&amp;ors=&amp;nots=&amp;tag=&amp;lang=all&amp;from=&amp;to=&amp;ref=&amp;near=&amp;within=15&amp;units=mi&amp;since=2009-05-13&amp;until=2009-05-17&amp;rpp=15">many others</a>. Despite the surprise revelations of Project X etc a particular slide caught my eye amongst the many others:</p>
<p style="text-align: center;"><a href="http://twitter.com/JimMcKeeth/status/1797365000"><img class="size-full wp-image-315 aligncenter" title="Delphi Targets" src="http://jamiei.com/blog/wp-content/uploads/2009/05/windowclipping.png" alt="Delphi Targets" width="601" height="292" /></a></p>
<p>Did you see it? ..ISVs, VARs, Consultants and<strong> Hobbyists.</strong>. I jumped at the phrase and asked Jim whether any of the Product Roadmaps he&#8217;d seen at <a href="http://www.delphilive.com">DelphiLive</a> had revealed any plans for a renewed focus on Turbo or Hobbyist editions of Delphi however it seems that they did not specifically mention anything. Luckily Jim had noticed the significance of this <span style="text-decoration: line-through;">typo</span> phrase too and was kind enough to pose my question to the new Delphi Product Manager, <a href="ttp://blogs.embarcadero.com/michaelrozlog/">Michael Rozlog</a>:</p>
<p><a href="http://twitter.com/JimMcKeeth/status/1810532948"><img class="aligncenter size-full wp-image-316" title="Hope" src="http://jamiei.com/blog/wp-content/uploads/2009/05/windowclipping-2.png" alt="Hope" width="607" height="294" /></a></p>
<p>I should make it entirely clear that this should <strong>not be read as a statement of intent</strong> from <a href="http://blogs.embarcadero.com/michaelrozlog/">Michael</a> or <a href="http://www.embarcadero.com">Embarcadero</a> but merely an indication of <a href="http://blogs.embarcadero.com/michaelrozlog/">Michael</a>&#8217;s personal thoughts on Turbo or Personal Delphi editions. This is encouraging news though, as many of you will know I wrote a long <a href="http://jamiei.com/blog/2009/02/turbo-delphi-an-open-letter/">Open letter to Codegear</a> on the subject of the sadly neglected Turbos and received a lot of feedback indicating that many of you felt the same way.</p>
<p><strong>So what now?</strong></p>
<p>Personally I&#8217;m thrilled that there seems to be at least some internal support for a renewed Turbo or Personal Delphi Edition but as usual, the devil is in the detail, How can we get a great home/hobbyist product (as opposed to a crippled and essentially useless product) without costing Codegear precious sales/revenue?</p>
<p>There are several different facets to this problem:</p>
<ul>
<li>What type of audience is the product is actually targetting? (Home users, Small ISVs, commercial vs strictly hobbyists?)</li>
<li>How should product be limited for that audience without damaging it&#8217;s viability or sales of the full product (As Delphi&#8217;s fate is intertwined with that of Codegear &#8211; not something we want).</li>
</ul>
<p>There are three different potential products in my mind:</p>
<ol>
<li>A Purchasable Commercial Product which is essentially a step down from Delphi Professional SKU in both price and features made for smaller software shops and developers that don&#8217;t need the features of the full versions.</li>
<li>A Non-commercially licensed product equivalent to the educational edition (which If I remember correctly is the Professional SKU?) where the price is a token amount to cover the cost of the bandwidth and packaging cost of the product.</li>
<li>A Commercially licensed but absolutely free product which is crippled in its functionality and features even more than the current Turbo Explorer Editions.</li>
</ol>
<p>As you might have guessed from my use of mildly emotive language in the 3rd point above and in my <a href="http://jamiei.com/blog/2009/02/turbo-delphi-an-open-letter/">Open Letter to Codegear</a> regarding the Turbos I consider the 3rd Option to be a non-offering. Sadly, previous statements from the former Delphi Product Manager, Nick Hodges, hinted that this was also the way he felt it might go.</p>
<p>I would be interested to see how the previous editions of Delphi impacted Sales (there must be paperwork, come on?) as I felt that these were always an amazing offering for Hobbyists and Home users wanting to take up the language (I remember finding Delphi 6 Personal on a <a href="http://www.pcw.co.uk">magazine</a> cover disc &#8211; presumably thanks to the always excellent <a href="http://itwriting.co.uk/">Tim Anderson</a>).</p>
<p>I would ideally like to see something in between the 2nd and 3rd options option a reality, I am not qualified to make a factual assertion on this but I don&#8217;t think it would hurt sales if <strong>strictly</strong> limited to non-commercial use in the license. Massive Feature limiting such as removing the ability to use 3rd Party VCL components as the Turbo Editions persued removes some of the most well-known and advantageous reasons for using Delphi in my opinion and is therefore unsuitable for an ambassador product (which these editions would be). I won&#8217;t rehash my argument about why the product needs to be both free and well featured (see my <a href="http://jamiei.com/blog/2009/02/turbo-delphi-an-open-letter/">Turbo Delphi Open Letter</a>) but I will say this:</p>
<blockquote><p>Whether it is fair or not, Microsoft and the Eclipse foundation have forced their hand &#8211; a reasonably useful free IDE for home and hobbyist users wanting to experiment with a language is now a minimum requirement for competitiveness in the programming language market.</p></blockquote>
<p>It is worth noting that the <a href="http://delphi.uservoice.com/pages/4432-general/suggestions/144386-release-an-up-to-date-turbo-delphi">Updated Personal or Turbo delphi</a> is currently only number 8 on the list requests at the <a href="http://delphi.uservoice.com/pages/4432-general">Delphi Uservoice</a> page, we really need people to vote for it and also to discuss their thoughts on the potential product in the comments over there.</p>
<p>Michael suggested that he was looking for feedback, so I&#8217;m looking for feedback. Firstly: What would your Turbo or Personal Product look like and secondly: what would you do if you were the Delphi Product Manager? How do the results of these two views differ? Please think about it and then either put it in the comments below or on the <a href="http://delphi.uservoice.com/pages/4432-general/suggestions/144386-release-an-up-to-date-turbo-delphi">Delphi Uservoice</a> page.</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/TI_X0ygIi38" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/05/turbo-delphi-a-hidden-gem-in-delphilive/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Diary of a C# to Delphi Prism conversion</title>
		<link>http://jamiei.com/blog/2009/04/diary-of-a-c-to-delphi-prism-conversion/</link>
		<comments>http://jamiei.com/blog/2009/04/diary-of-a-c-to-delphi-prism-conversion/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 14:15:25 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi Prism]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Podcast at Delphi]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[delphi prism]]></category>
		<category><![CDATA[project conversion]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=271</guid>
		<description><![CDATA[I have in the past written up a few tips for converting a Delphi.NET project to Delphi Prism but this time I thought it might be useful for me to write up my experiences on converting this C# Project to Delphi Prism by initially using the C#ToPas Tool from RemObjects. Many of you who attended CodeRage [...]]]></description>
			<content:encoded><![CDATA[<p>I have in the past written up a few tips for <a href="http://jamiei.com/blog/2008/12/migrating-a-project-to-delphi-prism-from-delphinet/">converting a Delphi.NET project to Delphi Prism</a> but this time I thought it might be useful for me to write up my experiences on converting this C# Project to Delphi Prism by initially using the C#ToPas Tool from RemObjects. Many of you who attended <a href="http://conferences.codegear.com/coderage08">CodeRage III</a> (in a virtual manner) might remember <a href="http://www.delphi.org">Jim McKeeth</a>&#8217;s <a href="http://www.delphi.org/robot-rage/">Revenge of Delphi Robot rage</a> session. The aim of the session was to build a <a href="http://www.unrealtournament3.com/">Unreal Tournament 3</a> Bot to fight it out against other competitor&#8217;s bots in an Unreal Tournament 3 arena using the (then) newly recently <a href="http://www.codegear.com/products/delphi/prism">Delphi Prism</a> tool. For those who didn&#8217;t attend, I&#8217;ll spoil the ending and just tell you that somehow <a href="http://www.delphi.org/2008/12/18-coderage-iii-wrap-up/">my bot won</a>. <img src='http://jamiei.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Jim is planning another session for the <a href="http://www.delphilive.com/">DelphiLive</a> conference (which I really wish I could go to, check it out if you haven&#8217;t already). However when running the last tournament we encountered a number of fatal bugs in the .NET UT3 Bot library which was originally put together by <a href="http://www.utbots.com/">Andy Sterland &amp; James Lissiak</a>. As a result Jim and I had been discussing the idea of porting the original library to Delphi Prism so that we could fix a few of the more serious bugs, it would also allow potential Prism Developers who were not familiar with C# to dig into the library itself. This is a project conversion diary which will outline the approaches I tried, any hurdles I encountered and a few tips for trying to avoid them when converting your own project.</p>
<p>I started by running the <a href="http://code.remobjects.com/p/csharptoxy/">C#ToOxygene</a> Tool on all of the source files within the project, It&#8217;s a very simple and easy to use tool that as its name implies aims to convert C# source files to Delphi Prism files. I was able to run the tool without issue on every C# source file except for 3 where for some reason it exited producing the error:  &#8221;<em><strong>Error during processing: Index was out of range</strong></em>&#8221; (Issue logged (rather clumsily) as #<a href="http://code.remobjects.com/p/csharptoxy/issues/37/">37</a>).</p>
<p>Having started on the basics of the translation using the conversion tool to do the grunt work I then dived into the code with the <a href="http://prismwiki.codegear.com/">Prism Wiki</a> and <a href="http://msdn.microsoft.com/en-us/library/618ayhy6(VS.80).aspx">MSDN C# documentation</a> open to make a start on correcting the <strong>600-odd errors</strong> that the resulting project produced upon an attempted Build.</p>
<p>At first glance I felt that the resultant code was a little bit visually &#8220;messy&#8221; in places and I felt it might be easier to prettify the code using a Code Formatter such as the <a href="http://jedicodeformat.sourceforge.net/">JEDI Code Format</a> tool to clean up the auto generated code and highlight any mismatched parenthesis or similar errors. However unfortunately the JEDI tool is not compatible with Prism and therefore refused to help me. If anyone knows of a Code Formatting tool which is compatible with Delphi Prism then please let me know in the comments below.</p>
<p>A few other issues which I encountered with the generated code or more generally are outlined below:</p>
<h3>Internal Keyword</h3>
<p><span style="font-weight: normal; font-size: 13px;">The C# <strong>internal</strong> (<a href="http://msdn.microsoft.com/en-us/library/7c5ka91b(VS.80).aspx">msdn doc</a>) keyword was not correctly translated &#8211; for this I took a trip to the Prism Wiki and looked up the <a href="http://prismwiki.codegear.com/en/Class_Member_Visibility_Levels">Class Member Visibility Levels</a> page to find that the equivalent level <strong>assembly</strong> is listed there (Issue #<a href="http://code.remobjects.com/p/csharptoxy/issues/42/">42</a>). Note that in Delphi Prism you can also have </span><span style="font-weight: normal; font-size: 13px;"><strong>assembly or protected</strong></span><span style="font-weight: normal; font-size: 13px;"> or </span><span style="font-weight: normal; font-size: 13px;"><strong>assembly and protected</strong></span><span style="font-weight: normal; font-size: 13px;"> depending upon whether you wish the class to be visible to descendants.</span></p>
<h3>The C# &#8220;this&#8221; Keyword</h3>
<p>The C# <strong>this.</strong> (<a href="http://msdn.microsoft.com/en-us/library/dk1507sz(VS.80).aspx">msdn doc</a>) keyword was not correctly translated to the Delphi Prism <strong>Self.</strong> equivalent that we&#8217;re all accustomed to. This isn&#8217;t hard to spot when going through the generated code and the issue had already been logged by Anton Kasyanov (Issue #<a href="http://code.remobjects.com/p/csharptoxy/issues/39/">39</a>) and should be fixed shortly.</p>
<h3>Float Types</h3>
<p>One class made extensive use of the <strong>float</strong> type (<a href="http://msdn.microsoft.com/en-us/library/b1e65aza(VS.80).aspx">msdn doc</a>) which doesn&#8217;t exist as is a built-in type for Delphi Prism so you&#8217;ll need to convert it to one of the <a href="http://prismwiki.codegear.com/en/Floats">two Float types</a> depending upon the precision you require.</p>
<h3>Operator Overloading</h3>
<p>Operator Overloading is not something that Delphi developers may be traditionally used to but Delphi Prism supports this nicely. However instead of using the sign operator that C# Developers use you&#8217;ll need to lookup the operator name and declaration on the <a href="http://prismwiki.codegear.com/en/Operator_Overloading">Operator Overloading Wiki Page</a>. eg. The Equals operator is declared as so:</p>
<pre class="brush: delphi;">class operator Equal(obj1, obj2: UTIdentifier): boolean;</pre>
<h3>Differences between return, Result and exit</h3>
<p>This should be obvious to any C# Developer but it could be easy to forget about. Don&#8217;t forget that the <strong>return</strong> C# method (<a href="http://msdn.microsoft.com/en-us/library/1h3swy84(VS.80).aspx">msdn doc</a>) terminates execution of the method in which it is being executed and returns to the calling method and therefore be wary of using <strong>Result</strong> blindly in an identical manner, particularly with boolean statements that rely upon this fact. Eg. Consider the following C# Code:</p>
<pre class="brush: csharp;">public override bool Equals(object obj)
{
	if (obj is UTVector)
	{
		if (this._x == ((UTVector)obj)._x &amp;&amp;
			this._y == ((UTVector)obj)._y &amp;&amp;
			this._z == ((UTVector)obj)._z)
		{
			return true;
		}
	}
	return false;
}</pre>
<p>Clearly, if you simply replace the <strong>return false;</strong> with <strong>Result := False;</strong> you will end up with a method that always returns False because the expression will always be executed no matter what Result is set to earlier in the method. In this case I simply moved the <strong>Result := false;</strong> to the top of the method. Delphi Prism also supports the <a href="http://prismwiki.codegear.com/en/Exit_(keyword)">Exit keyword</a> which also allows you to Return a result parameter. This method is a lot closer to the C# return keyword and usage but the <a href="http://prismwiki.codegear.com/en/Exit_(keyword)">Exit page</a> on the Prism Wiki warns against using too many exit keywords to avoid making the code harder to maintain.</p>
<h3>Constructors are not named</h3>
<p>This is a rare example of where the original C# code actually looks much closer to the end Delphi Prism code than a traditional Delphi programmer might think. In C# you might have a class and constructor that might look like this:</p>
<pre class="brush: csharp;">public class UTIdentifier
{
	internal UTIdentifier(string Id)
	{
	}
}</pre>
<p>In Prism, we have nameless <a href="http://prismwiki.codegear.com/en/Constructors">constructors</a> which means that the equivalent Delphi Prism constructor implementation might look like this:</p>
<pre class="brush: delphi;">  constructor UTIdentifier(id: String);
  begin
  end;</pre>
<p>It is important to note that in your class interface should adhere to this rule too. eg <strong>constructor(id: String);</strong></p>
<p>This was something that the C#ToPas tool also generated incorrectly. (Issue #<a href="http://code.remobjects.com/p/csharptoxy/issues/44/">44</a>)</p>
<h3>Short-Circuit Boolean Expressions</h3>
<p>I came across the C# <a href="http://msdn.microsoft.com/en-us/library/6373h346(VS.80).aspx"><strong>||</strong></a> operator which performs a short-circuited OR boolean evaluation of the operands. I wasn&#8217;t sure that the Delphi Prism <strong>or</strong> operator produces the same behaviour but if I read the <a href="http://prismwiki.codegear.com/en/Expression_Evaluation#Boolean_Short-Circuit_Evaluation">Expression Evaluation</a> page correctly then I believe it does (In Delphi 2009, at least, this behaviour is set through the <a href="http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsbooleanshortcircuitevaluation_xml.html">{$B+/-}</a> compiler flag) .</p>
<h3>Event Assignment</h3>
<p>The Event Assignment routine for multicast delegate type events is slightly different in Delphi Prism from what we&#8217;re used to in Delphi Win32. Looking at the <a href="http://prismwiki.codegear.com/en/Event_Assignment_Operators">Event Assignment</a> page in the wiki we can see that the actual method for assignment is much closer to the C# equivalent and uses the same C# <strong>+=</strong> and <strong>-=</strong> operators. The C#ToPas tool converted this code a little too literally converted this C# code:</p>
<pre class="brush: csharp;">this._connection.OnDataReceived += new EventHandler(DataReceived);
this._connection.OnErrorOccurred += new EventHandler(ErrorOccurred);</pre>
<p>to this:</p>
<pre class="brush: delphi;">Self._connection.OnDataReceived := Self._connection.OnDataReceived + new EventHandler(DataReceived);
Self._connection.OnErrorOccurred := Self._connection.OnErrorOccurred + new EventHandler(ErrorOccurred)</pre>
<p>Which produces a compiler Error that Events in Delphi Prism don&#8217;t allow access to the underlying field. You should use the += operator instead <a href="http://prismwiki.codegear.com/en/Event_Assignment_Operators">as seen on the Wiki</a>. (C#ToPas Issue logged as Issue #<a href="http://code.remobjects.com/p/csharptoxy/issues/45/">45</a>).</p>
<p><em>UPDATE: I&#8217;ve just noticed (after logging my own issue) that the event assignment issue has already been reported and has been marked as Won&#8217;t Fix (Issue #<a href="http://code.remobjects.com/p/csharptoxy/issues/27/">27</a>) so it looks like you&#8217;ll need to check _every_ event assignment in your project manually.</em></p>
<h3>Switch and Case Statements</h3>
<p>The C#ToPas tool did not appear to react well at all to use of the C# <a href="http://msdn.microsoft.com/en-us/library/06tc147t.aspx">switch</a> and case statements. I can&#8217;t give you any specific advice on how to fix these because each case statement was generated slightly differently in my converted code and therefore I can only advise that you check these manually or rewrite each of these methods by hand.</p>
<h3>Reserved Keywords</h3>
<p>Sadly this isn&#8217;t an issue that is related to the C#ToPas tool but more of an intrinsic difficulty when converting interoperable code between languages. I encountered at least one class that made use of a few reserved words in Delphi such as begin and end &#8211; I&#8217;m still not sure what to do with these for now.</p>
<h3>Overall Impression</h3>
<p>Despite a few early bugs the <a href="http://code.remobjects.com/p/csharptoxy/">C#ToPas</a> Tool is a good platform to begin converting your C# code to Delphi Prism although you may wish to ensure that you have some extensive Unit Tests for your code before the main code is converted so as to ensure that any bugs introduced can be picked up on quickly (which you have anyway right?). It is also worth noting that the <a href="http://prismwiki.codegear.com">Delphi Prism Wiki</a> (which now <a href="http://blogs.remobjects.com/blogs/mh/2009/04/27/p277">authenticates via your CDN login</a>) has <strong>excellent coverage</strong> and is an absolutely <strong>invaluable reference</strong> for anyone working with Delphi Prism.</p>
<p>By the time this entry is published I suspect that <a href="http://blogs.remobjects.com/blogs/ck/">Carlo</a> will be very close to fixing some or most of the above bugs in the C#ToPas tool.</p>
<p>The code is nowhere near complete yet and most of the files are still straight out of the Automatic conversion and therefore <strong>will not compile in any way</strong> but I&#8217;ve put what we have so far up on the rather smooth <a href="http://www.github.com">Github</a> site at the <a href="http://github.com/jamiei/PrismUT3RemoteBot">PrismUT3RemoteBot</a> project which anyone can fork and push changes back to. <a href="http://git-scm.com/">Git</a> is a little strange to work with at first because it&#8217;s a different mindset to SubVersion/CVS but it&#8217;s worth checking out if you haven&#8217;t already.</p>
<p>[<strong>UPDATE</strong>: The Prism UT3 Remote Bot conversion project has been completed since this original post and may be used during Jim McKeeth's session at <a href="http://www.delphilive.com/">DelphiLive! Germany Sept 28 - Oct 2 2009</a>.]</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/oDy8Jh9N9BM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/04/diary-of-a-c-to-delphi-prism-conversion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Developer / Utility Toolbox</title>
		<link>http://jamiei.com/blog/2009/04/my-developer-utility-toolbox/</link>
		<comments>http://jamiei.com/blog/2009/04/my-developer-utility-toolbox/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 14:23:26 +0000</pubDate>
		<dc:creator>jamiei</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[apps-i-love]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://jamiei.com/blog/?p=243</guid>
		<description><![CDATA[Most Developers will already have come accross many of these tools but just as every plumber has a favoured brand of wrench or electrician has a favoured model of multi-meter we all have a favourite set of productivity enhancing utilities. Here are a few of the tools which I find tremendously useful or find developing [...]]]></description>
			<content:encoded><![CDATA[<p>Most Developers will already have come accross many of these tools but just as every plumber has a favoured brand of wrench or electrician has a favoured model of multi-meter we all have a favourite set of productivity enhancing utilities. Here are a <strong>few</strong> of the tools which I find tremendously useful or find developing without particularly painful. Writing up a small list of these utilities also helps me more than it may help you because it&#8217;ll also serve as a todo list for any new workstation that I want to set myself up on in the future.</p>
<p>(Items marked with an Asterisk * are non-free)</p>
<h3>Delphi Tools</h3>
<p><a href="http://www.gexperts.org/"><strong>GExperts</strong></a> &#8211; Every Delphi Developer should have GExperts, adding a fantastic selection of features to the Delphi IDE and Editor.</p>
<p><a href="http://www.cnpack.org/">cnWizard IDE</a> &#8211; Quite a few commenters suggested adding cnWizard IDE here, I&#8217;ve never actually tried it but did consider it against GExperts. What put me off was the relatively uninformative website (yes, shallow of me but I can&#8217;t help it!).</p>
<div id="attachment_260" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-260" title="scconfiguration" src="http://jamiei.com/blog/wp-content/uploads/2009/04/scconfiguration-300x240.png" alt="DelphiCodeToDoc Options" width="300" height="240" /><p class="wp-caption-text">DelphiCodeToDoc Options</p></div>
<p><a href="http://dephicodetodoc.sourceforge.net/"><strong>DelphiCodeToDoc</strong></a> &#8211; Generate documentation from your Delphi Source comments, including JavaDoc compatible comments. DelphiCodeToDoc is open source and can generate Windows Help Files or HTML Documentation (or both).</p>
<p><a href="http://www.gurock.com/products/smartinspect/"><strong>SmartInspect</strong></a>* - This is a commercial product which gives you amazing code logging features for Delphi, .NET and Java applications (and <a href="http://blog.gurock.com/postings/smartinspect-for-php-logging/347/">even PHP too now</a> which I also find useful). No more inserting breakpoints, watches and spurious ShowMessages()&#8217;s just to track the variables in an application. Even allows Remote Logging when an executable is deployed on a different machine. Saved me from a particuarly frustrating problem in a remote app recently.</p>
<div id="attachment_254" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-254" title="smartinspect-professional-console" src="http://jamiei.com/blog/wp-content/uploads/2009/04/smartinspect-professional-console-300x180.png" alt="SmartInspect Console" width="300" height="180" /><p class="wp-caption-text">SmartInspect Console</p></div>
<p><a href="http://www.jrsoftware.org/isinfo.php"><strong>Innosetup</strong></a> &#8211; A Free installer which allows you to create fully customisable installers which support nearly every version of windows and even 64 bit architectures. I&#8217;ve also found it to be just as functional and much easier to use than some of it&#8217;s expensive <a href="http://www.acresso.com/products/is/installshield-overview.htm">competitors</a>.  Did I mention it&#8217;s also free?</p>
<p><a href="http://v.mahon.free.fr/pro/freeware/memcheck/"><strong>MemCheck</strong></a> &#8211; Not really an application per se. Not fully Delphi 2009 compatible yet but this is a useful little unit that means adding a single line to your project file and then creates a log file of the memory leaks in your application.</p>
<p><a href="http://www.want-tool.org/"><strong>WAnt</strong></a> &#8211;  A Delphi specific Build Automation tool in the same fashion as the Java Ant tool. I looked into this tool recently because I wanted a way to automatically Checkout, Build and Test the <a href="http://www.delphi.org/twitter/dwitterphi">Dwitterphi</a> project that I&#8217;m working on so I know when the SVN Trunk has been broken.</p>
<h3>Editors / IDEs</h3>
<p><a href="http://www.pnotepad.org/"><strong>Programmers Notepad 2</strong></a> &#8211; A General Purpose Notepad replacement which includes Syntax highlighting support, bookmarks, code folding, project and project group support and all the usual gubbins which you would expect from a lightweight notepad replacement.</p>
<p><a href="http://www.zend.com/products/studio/"><strong>Zend Studio</strong></a>* &#8211; My copy is a few years old, before they switched to Eclipse. I&#8217;m actually looking at replacing this with something newer and free.</p>
<div id="attachment_255" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-255" title="zend-development-environment" src="http://jamiei.com/blog/wp-content/uploads/2009/04/zend-development-environment-300x180.png" alt="Zend Development Environment (older version)" width="300" height="180" /><p class="wp-caption-text">Zend Development Environment (older version)</p></div>
<p><a href="http://www.eclipse.org"><strong>Eclipse</strong></a> &#8211; Needs no real introduction. A Base for so many tools. I also use the <a href="http://www.aptana.com/rails">RadRails</a> package for Rails and Ruby Development.</p>
<h3>Version Control / File Comparison</h3>
<p><a href="http://www.scootersoftware.com/"><strong>Beyond Compare 3</strong></a>* &#8211; An amazing File Comparison utility with 3 way merge capability, folder sync capabilities, specialised viewers for various file types and remote comparison tools. I&#8217;ve mentioned it many times before but this is an essential tool for developers.</p>
<div id="attachment_256" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-256" title="Beyond Compare 3" src="http://jamiei.com/blog/wp-content/uploads/2009/04/beyond-compare-300x180.png" alt="Beyond Compare 3" width="300" height="180" /><p class="wp-caption-text">Beyond Compare 3</p></div>
<p><a href="http://tortoisesvn.tigris.org/"><strong>Toroise SVN</strong></a> &#8211; Easy to use interface for Subversion which integrates beautifully with the Windows Shell. My only gripe with this particular tool is that it seems to bug you often to download the latest updates when they should by now have implemented an auto-update feature.</p>
<p><a href="http://svnmonitor.com/default.shtml"><strong>SVNMonitor</strong></a> &#8211; Only Recently suggested to me by <a href="http://twitter.com/dmillam/status/1553857414">@dmiliam</a> via Twitter. I installed it and found it tremendously useful for keeping tabs on whats happening with a SVN Repository.</p>
<h3>Internet</h3>
<p><a href="http://www.smartftp.com/"><strong>SmartFTP</strong></a>* &#8211; There are a million FTP Clients out there, some are free with comparable features to SmartFTP but none come close to the overall package and polish that SmartFTP represents including support for FTPS and SFTP and very smooth transfer queues and folder sync features.</p>
<p><a href="http://www.newsgator.com/Individuals/FeedDemon/Default.aspx"><strong>FeedDemon</strong></a> &#8211; Developed in Delphi by Nick Bradbury. It&#8217;s considered very <em>cool</em> to use Google Reader nowadays but you can&#8217;t beat the stability and power of a Desktop Reader and FeedDemon has it all. Fast and efficient, especially good when combined with the NewsGator Online Sync Service that allows me to sync unread/read items to my Work PC or even my Blackberry with NewsGator Go! and catch up with news on the go. Sync with Google Reader is also <a href="http://nick.typepad.com/blog/2009/01/feeddemon-to-sync-with-google-reader.html">on the way</a>. FeedDemon FTW.</p>
<div id="attachment_257" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-257" title="FeedDemon 3" src="http://jamiei.com/blog/wp-content/uploads/2009/04/newsgator-feeddemon-30015-beta-3-300x180.png" alt="FeedDemon 3" width="300" height="180" /><p class="wp-caption-text">FeedDemon 3</p></div>
<p><a href="http://www.twhirl.org/"><strong>twhirl</strong></a> &#8211; I prefer twhirl as my Twitter client of choice as it isn&#8217;t as big and bulky as TweetDeck but all that will change when there is a <a href="http://www.delphi.org/twitter/dwitterphi">great native win32 twitter client</a>.</p>
<h3>Browser</h3>
<p><a href="http://www.mozilla.com/firefox"><strong>FireFox</strong></a> &#8211; No explaination neccessary really.</p>
<ul>
<li><a href="http://chrispederick.com/work/web-developer/"><strong>Web Developer Toolbar</strong></a> &#8211; Simply indispensable for those who spend a great deal of time crafting Browser content or applications.</li>
<li><a href="http://developer.yahoo.com/yslow/"><strong>YSlow</strong></a> &#8211; I&#8217;ll be honest: I&#8217;ve never had a site that is big enough to need the level of optimisation that Yahoo.com does but the advice this tool gives is sound and it will help you to identify bottlenecks in your sites performance.</li>
<li><a href="http://getfirebug.com/"><strong>FireBug </strong></a> - Edit, debug, and monitor HTML, CSS and JavaScript live in any web page.</li>
</ul>
<p><a href="http://www.google.com/chrome"><strong>Google Chrome</strong></a> &#8211; Used for Day to Day browsing because it&#8217;s an order of magnitude faster than almost any other browser out there in general browsing (Just my opinion).</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=8e6ac106-525d-45d0-84db-dccff3fae677&amp;displaylang=en"><strong>SuperPreview</strong></a> &#8211; A fabulous tool from Microsoft unveiled at <a href="http://live.visitmix.com/">Mix09</a> which allows you to view web pages in Internet Explorer 6, 7 and 8 as well as your other browsers whilst allowing you to super-impose expected layouts on top of one another to see how the renderings differ. No more hefty VMs required for testing layouts.. great success!</p>
<h3>Shell / Miscellaneous</h3>
<div id="attachment_261" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-261" title="CommandPromptHere" src="http://jamiei.com/blog/wp-content/uploads/2009/04/untitled-300x175.png" alt="Open Command Window Here shortcute" width="300" height="175" /><p class="wp-caption-text">Open Command Window Here shortcute</p></div>
<p><a href="http://www.jrsoftware.org/misc.php"><strong>Command Prompt Here</strong></a><strong> </strong>- A hugely underrated and disarmingly simple shell extension which adds an &#8220;Open Command Prompt Here&#8221; sub-item to the context menu in Windows Explorer. No more cd &#8220;C:really really really long path name&#8221; for these users.</p>
<p><a href="http://www.realtimesoft.com/ultramon/"><strong>UltraMon</strong></a>* &#8211; This improves the Multi-Monitor support in Windows hugely, something that if you haven&#8217;t tried it, try it now! Monitor specific task bars, extra system buttons on each window, wallpaper and desktop icon management. Ultramon is so useful that I&#8217;m suprised it hasn&#8217;t already been acquired by Microsoft like the SysInternals team were.</p>
<div id="attachment_265" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-265" title="process-explorer-sysinternals" src="http://jamiei.com/blog/wp-content/uploads/2009/04/process-explorer-sysinternals1-300x180.png" alt="ProcessExplorer from SysInternals" width="300" height="180" /><p class="wp-caption-text">ProcessExplorer from SysInternals</p></div>
<p><a href="http://technet.microsoft.com/en-gb/sysinternals/default.aspx"><strong>SysInternals</strong></a> &#8211; From by <a id="ctl00_mainContentContainer_ctl03_ctl02" onclick="javascript:Track('ctl00_mainContentContainer_ctl03_ctl01|ctl00_mainContentContainer_ctl03_ctl02',this);" href="http://blogs.technet.com/markrussinovich/about.aspx">Mark Russinovich</a> and Bryce Cogswell, The best set of power user utilities available out there, Acquired by Microsoft a few years ago. My personal favourites are:</p>
<ul>
<li> <a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx"><strong>Process Explorer</strong></a> &#8211; Think of the windows task manager on steroids, double it and then add more.</li>
<li><a href="http://technet.microsoft.com/en-us/sysinternals/bb963902.aspx"><strong>Autoruns</strong></a> &#8211; Comprehensive lists of everything starting up when your computer does.</li>
<li><a href="http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx"><strong>ps* Utils</strong></a> &#8211; Lightweight remote versions of your favourite windows commands.</li>
</ul>
<p><a href="http://www.virtualbox.org/"><strong>VirtualBox</strong></a> &#8211; A Free and Open Source VM competitor to Microsoft VirtualPC and VMWare etc. Not as polished as VMWare in some parts of the user interface or networking features but very usable and getting much better with every release.</p>
<p><a href="http://www.windowclippings.com/"><strong>Window Clippings</strong></a>* &#8211; Recommended to me by marc hoffman (although how he knew about it &#8211; primarily being a mac user I&#8217;m not sure). A very easy Screenshot and Window Clipping tool. Great features, addons available and inexpensive. Everyone has their own preference for a Screenshot tool so whilst I would completely recommend this, I wouldn&#8217;t push for you to change over any other.</p>
<p><a href="http://www.microsoft.com/windowsxp/downloads/powertoys/xppowertoys.mspx"><strong>Power Toys</strong></a> &#8211; An amazing set of utilities that add to windows.</p>
<p><a href="http://blogs.msdn.com/sync/archive/2008/08/14/now-available-synctoy-2-0-file-synchronization.aspx"><strong>SyncToy</strong></a><strong> </strong>2 - A File and Folder Synchronisation tool that I use to keep files backed up to my home servers and which I will use to Sync important indispensable files (music!) to my NetBook when I finally purchase it!</p>
<p>This isn&#8217;t a completely comprehensive list (I&#8217;m not going to dump a list of everything from Windows Add/Remove Programs!) but I&#8217;d love to hear if you think I&#8217;m missing out on any spectacularly useful utilities for Delphi or Web Development. Hopefully you found at least one utility in this list that you&#8217;ve been putting off trying and have realised why I found it to be useful.</p>
<img src="http://feeds.feedburner.com/~r/NullReference/~4/7BGaUU5qTI8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jamiei.com/blog/2009/04/my-developer-utility-toolbox/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 1.164 seconds -->
