<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>YAPB</title>
	<atom:link href="http://alex.ciobanu.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://alex.ciobanu.org</link>
	<description>Yet Another Programming Blog</description>
	<lastBuildDate>Thu, 17 Jun 2010 21:27:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>DeHL 0.8.3</title>
		<link>http://alex.ciobanu.org/?p=358</link>
		<comments>http://alex.ciobanu.org/?p=358#comments</comments>
		<pubDate>Thu, 17 Jun 2010 21:27:59 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[BSD]]></category>
		<category><![CDATA[DeHL]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[RTL]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=358</guid>
		<description><![CDATA[I will be brief as usual &#8212; version 0.8.3 of DeHL is out. The downloads can be found on this page and changelog on this page. This release &#8220;fixes&#8221; some of the things I wanted fixed for a long time, so it seemed this is the perfect moment for this to happen. A new unit [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-242" href="http://alex.ciobanu.org/?attachment_id=242"><img class="alignleft size-full wp-image-242" title="DeHL" src="http://alex.ciobanu.org/files/uploads/2009/06/Logo_2.png" alt="DeHL" width="100" height="100" /></a></p>
<p>I will be brief as usual &#8212; version 0.8.3 of DeHL is out. The downloads can be found on <a href="http://code.google.com/p/delphilhlplib/downloads/list">this</a> page and changelog on <a href="http://code.google.com/p/delphilhlplib/source/browse/tags/0.8.3/changelog.txt">this</a> page. This release &#8220;fixes&#8221; some of the things I wanted fixed for a long time, so it seemed this is the perfect moment for this to happen. A new unit is introduced &#8212; <em>DeHL.Tuples</em> &#8212; which brings seven generic <strong>Tuple&lt;&#8230;&gt;</strong> types. I have also finished moving away from Integer and Cardinal to NativeInt and NativeUInt through all DeHL.</p>
<p>Breaking changes are:</p>
<ol>
<li><em>DeHL.Converter</em> was renamed to <em>DeHL.Conversion</em>. This name change was done mostly to reflect the nature of the unit. It does not contain one simple class anymore. Now there is a fully featured conversion system.</li>
<li><strong>TBinaryTree&lt;T&gt;</strong> (in <em>DeHL.Collections.BinaryTree</em>) is no more. It was written way in the beginnings of the project and was buggy, incomplete and utterly useless.</li>
<li>And the most visible and breaking of all changes is the removal of <strong>TKeyValuePair&lt;TKey, TValue&gt;</strong> (in <em>DeHL.KeyValuePair</em>). It was replaced with <strong>KVPair&lt;TKey, TValue&gt;</strong> (in <em>DeHL.Tuples</em>). The easiet way to get over this change is to find and replace all TKeyValuePair instances with KVPair and all DeHL.KeyValuePair uses with DeHL.Tuples.</li>
</ol>
<p>Now, obviously an example using Tuples:</p>
<pre class="brush: delphi">
uses
  SysUtils, DeHL.Tuples;

{ If you are lazy and do not wish to declare a new record type
  to be used as result. Use Tuple&lt;..&gt; do to that. }
function GiveMeSomeData(): Tuple&lt;String, Integer, Integer&gt;;
begin
  { ... Do some processing ... }
  Result := Tuple.Create(&#039;Some data&#039;, 100, -99);
end;

var
  LResult: Tuple&lt;String, Integer, Integer&gt;;
begin
  { Obtain the result }
  LResult := GiveMeSomeData();

  { And write the results to the console }
  with LResult do
    WriteLn(&#039;Something was done with result: &#039;, Value1, &#039;, &#039;,
      Value2, &#039;, &#039;, Value3, &#039;!&#039;);
end.
</pre>
<p>The new conversion engine handles most of the possible conversions and also allows registering custom ones:</p>
<pre class="brush: delphi">
uses
  SysUtils,
  DeHL.Conversion,
  DeHL.Collections.List;

type
  { Declare some type that cannot be converted into integer directly.
    We&#039;re making up an &quot;int&quot;. }
  TRecordInt = packed record
    FValueAsString: string;
    FSign: Boolean;

    constructor Create(const AInt: Integer);
  end;

{ TRecordInt }

constructor TRecordInt.Create(const AInt: Integer);
begin
  { Decompose an int }
  FValueAsString := IntToStr(Abs(AInt));
  FSign := (AInt &lt; 0);
end;

var
  LInputList: TList&lt;TRecordInt&gt;;
  S: String;
  I: Integer;
begin
  { Create a list of TRecordInt }
  LInputList := TList&lt;TRecordInt&gt;.Create();

  { Fill it with some random values (positive and negative) }
  for I := 0 to 10 do
    LInputList.Add(TRecordInt.Create(Random(MaxInt) - (MaxInt div 2)));

  { Now comes the interesting part ... register a custom converter
    from TRecordInt to Integer }
  TConverter&lt;TRecordInt, Integer&gt;.Method :=
    function(const AIn: TRecordInt; out AOut: Integer): Boolean
    begin
      { Convert the TRecordInt back to an integer }
      Result := TryStrToInt(AIn.FValueAsString, AOut);
      if Result and AIn.FSign then
        AOut := -AOut;
    end;

  { Now print the values to the console. Convert them from TRecordInt to
    Integer then to String }
  for S in LInputList.Op.Cast&lt;Integer&gt;.Op.Cast&lt;String&gt; do
    WriteLn(S);
end.
</pre>
<p><strong>TConverter</strong> is also smart enough to figure out that <em>&#8220;type MyInt = type Integer&#8221;</em> is actually equivalent to <strong>Integer</strong>. If there is no explicit custom conversion method registered for it the converter for the standard type will be selected is possible. In the worst case, when TConverter cannot convert directly between the given types, it falls back to Variant conversion (using <em>TType<T>.TryConvertToVariant</em> and <em>TType<T>.TryConvertFromVariant</em>) which all types registered with DeHL&#8217;s type system,  if possible, should implement.</p>
<p>Well, that&#8217;s all for today,<strong><br />
Have Fun!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=358</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>DeHL 0.8.2 is out</title>
		<link>http://alex.ciobanu.org/?p=336</link>
		<comments>http://alex.ciobanu.org/?p=336#comments</comments>
		<pubDate>Tue, 18 May 2010 15:03:51 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[DeHL]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[RTL]]></category>
		<category><![CDATA[RTTI]]></category>
		<category><![CDATA[Unicode]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=336</guid>
		<description><![CDATA[I&#8217;ve just released the version 0.8.2 of DeHL. The downloads can be found on this page and changelog on this page. Again, this is a minor release with a few bugs fixed and a new feature: TString (as asked in this comment). As you might have guessed already, TString is a wrapper record modeled on [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-242" href="http://alex.ciobanu.org/?attachment_id=242"><img class="alignleft size-full wp-image-242" title="DeHL" src="http://alex.ciobanu.org/files/uploads/2009/06/Logo_2.png" alt="DeHL" width="100" height="100" /></a></p>
<p>I&#8217;ve just released the version 0.8.2 of DeHL. The downloads can be found on <a href="http://code.google.com/p/delphilhlplib/downloads/list">this</a> page and changelog on <a href="http://code.google.com/p/delphilhlplib/source/browse/tags/0.8.2/changelog.txt">this</a> page.<br />
Again, this is a minor release with a few bugs fixed and a new feature: <strong>TString</strong> (as asked in <a href="http://alex.ciobanu.org/?p=331&amp;cpage=1#comment-1298">this comment</a>).<br />
As you might have guessed already, TString is a wrapper record modeled on .NET&#8217;s <a href="http://msdn.microsoft.com/en-us/library/system.string.aspx">System.String</a> class. Unfortunately I was unable to use most of the RTL&#8217;s string functionality so the &#8220;wrapper&#8221; grew quite a bit from my original expectations.</p>
<p>But &#8230; enough talk, here are some usage scenarios that someone may find useful:</p>
<pre class="brush: delphi">
var
  LStr: TString;
begin
  { Overloaded operators and a special function &quot;U&quot; }
  LStr := U(&#039;Hello World for the &#039;) + 10 + &#039;th time!&#039;;

  { Do some random operations }
  if (LStr.ToUpper().Contains(&#039;HELLO&#039;)) and
     (LStr.Contains(&#039;HeLLo&#039;, scLocaleIgnoreCase)) then
  WriteLn(LStr.ToString);

  { Now let&#039;s select all the distinct chars from the string }
  WriteLn(
    LStr.Concat(LStr.AsCollection.Distinct.Op.Cast&lt;string&gt;).ToString
  );
end.
</pre>
<p>TString overloads all sane operators: Equality, Inequality, Implicit conversions, Addition, Subtraction and offers functions to convert to and from UTF8 and UCS4 (via RTL of course). I also need to iron a few things about about Enex integration for the next minor release.</p>
<p>The other small improvement that I added relates to the collection package. All simple collections (not the Key/Value pair ones) implement a sort of <i>&#8220;where T is the_class, select it as such&#8221;</i> operation. Check out this example:</p>
<pre class="brush: delphi">
var
  LList: TList&lt;TObject&gt;;
  LBuilder: TStringBuilder;
  LObject: TObject;
begin
  LList := TList&lt;TObject&gt;.Create;

  { Populate the list with some random objects }
  LList.Add(TInterfacedObject.Create);
  LList.Add(TStringBuilder.Create);
  LList.Add(TStringBuilder.Create);
  LList.Add(TObject.Create);

  { Now select the objects we&#039;re interested in (string builders) }
  for LBuilder in LList.Op.Select&lt;TStringBuilder&gt; do
    WriteLn(LBuilder.ClassName); // Do stuff

  { Or select everything (not actually required - an example) }
  for LObject in LList.Op.Select&lt;TObject&gt; do
    WriteLn(LObject.ClassName); // Do stuff
end.
</pre>
<p>If it&#8217;s still not clear what this operations does, let me explain. It basically consists of two operations: <i>Where</i> and <i>Select</i>. First, each <strong>object</strong> is checked to be of a given class and then this object is cast to that class so you can iterate directly using a <i>FOR .. IN</i> loop only over the objects you want to. Of course doing that for TObject makes no sense (as in example) &#8230; but well &#8230; that was an example.</p>
<p>Well, that&#8217;s all for today,<strong><br />
Have Fun!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=336</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DeHL 0.8.1</title>
		<link>http://alex.ciobanu.org/?p=331</link>
		<comments>http://alex.ciobanu.org/?p=331#comments</comments>
		<pubDate>Mon, 19 Apr 2010 15:51:23 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[DeHL]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[RTL]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=331</guid>
		<description><![CDATA[I&#8217;ve just released the version 0.8.1 of DeHL. The downloads can be found on this page and changelog on this page. This is mostly a fix release with only one major feature &#8211; Cloning (in DeHL.Cloning). The rest of the changes are either bug fixes or janitorial changes. Have Fun!]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-242" href="http://alex.ciobanu.org/?attachment_id=242"><img class="alignleft size-full wp-image-242" title="DeHL" src="http://alex.ciobanu.org/files/uploads/2009/06/Logo_2.png" alt="DeHL" width="100" height="100" /></a></p>
<p>I&#8217;ve just released the version 0.8.1 of DeHL. The downloads can be found on <a href="http://code.google.com/p/delphilhlplib/downloads/list">this</a> page and changelog on <a href="http://code.google.com/p/delphilhlplib/source/browse/tags/0.8.1/changelog.txt">this</a> page.</p>
<p>This is mostly a fix release with only one major feature &#8211; Cloning (in <em>DeHL.Cloning</em>). The rest of the changes are either bug fixes or janitorial changes.</p>
<p><strong>Have Fun!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=331</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Replication</title>
		<link>http://alex.ciobanu.org/?p=325</link>
		<comments>http://alex.ciobanu.org/?p=325#comments</comments>
		<pubDate>Thu, 18 Mar 2010 22:50:07 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[DeHL]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[RTL]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=325</guid>
		<description><![CDATA[I must say, I am still pretty exited by the extended RTTI in Delphi 2010. It makes life so much easier in many circumstances. &#8220;Cloning&#8221; (I call it replication) is one of those. Say hello to TReplicator&#60;T&#62; (in DeHL.Replication). It can take any type and create an exact copy (including deep cloning for complex types). [...]]]></description>
			<content:encoded><![CDATA[<p>I must say, I am still pretty exited by the extended RTTI in Delphi 2010. It makes life so much easier in many circumstances. &#8220;Cloning&#8221; (I call it <em>replication</em>) is one of those. Say hello to <strong>TReplicator&lt;T&gt;</strong> (in <em>DeHL.Replication</em>). It can take any type and create an exact copy (including deep cloning for complex types).</p>
<p>The following example should pretty much explain what and how:</p>
<pre class="brush: delphi">
uses
  SysUtils,
  DeHL.Replication,
  DeHL.Collections.List;

type
  { Define a test class }
  TData = class
    { Pointer to self }
    FSelf: TObject;

    { A chunck of bytes }
    FSomeData: TBytes;

    { Some dummy string }
    FName: string;

    { An internal pointer. Marked as non-replicable -- will not be copied }
    [NonReplicable]
    FInternalPtr: Pointer;

    { This field will be copied by reference. It means that the new
      object will have the reference to the same TList&lt;String&gt; and not
      a copy of it. }
    [ByReference]
    FList: TList&lt;String&gt;;
  end;

var
  LInput, LOutput: TData;
  LReplicator: TReplicator&lt;TData&gt;;
begin
  { Create the input }
  LInput := TData.Create;
  LInput.FSelf := LInput;
  LInput.FSomeData := TBytes.Create(1, 2, 3, 4, 5, 6);
  LInput.FName := &#039;Some Name&#039;;
  LInput.FInternalPtr := Ptr($DEADBABE);
  LInput.FList := TList&lt;String&gt;.Create([&#039;Hello&#039;, &#039;World&#039;]);

  { Create the replicator }
  LReplicator := TReplicator&lt;TData&gt;.Create;

  { Create a copy of LInput }
  LReplicator.Replicate(LInput, LOutput);

  { ... }
end.
</pre>
<p>As you can see we take <span style="text-decoration: underline;">LInput</span> and create a copy into <span style="text-decoration: underline;">LOutput</span>. Also note the use of <strong>[NonReplicable]</strong> and <strong>[ByReference]</strong> attributes on two fields of <span style="text-decoration: underline;">TData</span> class. <em>NonReplicable</em> forces the replication process to skip the field and <em>ByReference</em> forces a shallow copy of reference fields (objects, pointers to arrays and dynamic arrays).</p>
<p>For the ease of use, a <strong>TCloneableObject</strong> is defined in the same unit (<em>DeHL.Replication</em>). TCloneableObject provides a method called <em>Clone()</em> which returns a copy of the object:</p>
<pre class="brush: delphi">
uses
  SysUtils,
  DeHL.Replication;

type
  { Define a test class }
  TTestMe = class(TCloneableObject)
    { ... }
  end;

var
  LInput, LOutput: TTestMe;
begin
  { ... }
  LOutput := LInput.Clone() as TTestMe;
  { ... }
end.
</pre>
<p><span style="color: #ff0000;"><strong>Note: This is just a preview of a new feature finding it&#8217;s way into DeHL. It&#8217;s currently only in the SVN repository. As usual, I need to write unit tests and so on to make sure it actually has no bugs (or at leas not that many bugs <img src='http://alex.ciobanu.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</strong></span></p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=325</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Here you go &#8212; DeHL 0.8</title>
		<link>http://alex.ciobanu.org/?p=300</link>
		<comments>http://alex.ciobanu.org/?p=300#comments</comments>
		<pubDate>Tue, 16 Mar 2010 12:16:15 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[DeHL]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[RTL]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=300</guid>
		<description><![CDATA[This is going to be a short one. After months of no releases, here it is: DeHL 0.8 (see changelog for the list of changes on this release). As I mentioned previously, this release will only work on Delphi 2010, since the number of changes required to support serialization was quite big. I must confess, [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-242" href="http://alex.ciobanu.org/?attachment_id=242"><img class="alignleft size-full wp-image-242" title="DeHL" src="http://alex.ciobanu.org/files/uploads/2009/06/Logo_2.png" alt="DeHL" width="100" height="100" /></a></p>
<p>This is going to be a short one. After months of no releases, here it is: <a href="http://delphilhlplib.googlecode.com/files/DeHL_0.8.0.zip">DeHL 0.8</a> (see <a href="http://code.google.com/p/delphilhlplib/source/browse/tags/0.8/changelog.txt">changelog</a> for the list of changes on this release). As I mentioned previously, this release will only work on Delphi 2010, since the number of changes required to support serialization was quite big.</p>
<p>I must confess, this is the first time in my programming career that I had to interact with serialization (excluding the times when the frameworks do that for you). I had to learn quite a bit and changed my internal design three times.</p>
<p>So, here&#8217;s an example how to serialize a <strong>TFormatSettings</strong> structure into binary format:</p>
<pre class="brush: delphi">
var
  LBinFile: TFileStream;
  LBinSerializer: TBinarySerializer&lt;TFormatSettings&gt;;
  LSettings: TFormatSettings;
begin
  { Obtain current thread&#039;s format settings }
  GetFormatSettings(GetThreadLocale(), LSettings);

  { Create a serializer and a file stream }
  LBinSerializer := TBinarySerializer&lt;TFormatSettings&gt;.Create();
  LBinFile := TFileStream.Create(&#039;dump_obj.bin&#039;, fmCreate);

  { Serialize the structure }
  try
    LBinSerializer.Serialize(LSettings, LBinFile);
  finally
    LBinFile.Free;
    LBinSerializer.Free;
  end;
end;
</pre>
<p>&#8230; and here&#8217;s an example how to deserialize it:</p>
<pre class="brush: delphi">
var
  LBinFile: TFileStream;
  LBinSerializer: TBinarySerializer&lt;TFormatSettings&gt;;
  LSettings: TFormatSettings;
begin
  { Create a serializer and a file stream }
  LBinSerializer := TBinarySerializer&lt;TFormatSettings&gt;.Create();
  LBinFile := TFileStream.Create(&#039;dump_obj.bin&#039;, fmOpenRead);

  { Deserialize the structure }
  try
    LBinSerializer.Deserialize(LSettings, LBinFile);
  finally
    LBinFile.Free;
    LBinSerializer.Free;
  end;
end;
</pre>
<p><em>Note: I have written quite a few unit tests to support the new changes, but most certainly there are hidden bugs. If you find one please report it <a href="http://code.google.com/p/delphilhlplib/issues/list">here</a>.</em></p>
<p><em>Other Note: I exhausted my idea jar regarding new features. If you have an idea please do not hesitate to drop me a comment or an email.</em></p>
<p><strong>Have Fun!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=300</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>DeHL, Delphi 2010 and Serialization</title>
		<link>http://alex.ciobanu.org/?p=285</link>
		<comments>http://alex.ciobanu.org/?p=285#comments</comments>
		<pubDate>Wed, 03 Feb 2010 14:33:31 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[DeHL]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[RTL]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=285</guid>
		<description><![CDATA[A few months have passed and I did not release a new version of DeHL yet. No, it&#8217;s not dead. I&#8217;ve just been busy with a delicate new feature &#8212; Serialization. This post will demonstrate the new capabilities of DeHL it&#8217;s advantages and and shortcomings. But first &#8212; since the new releases will focus mostly [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-242" href="http://alex.ciobanu.org/?attachment_id=242"><img class="alignleft size-full wp-image-242" title="DeHL" src="http://alex.ciobanu.org/files/uploads/2009/06/Logo_2.png" alt="DeHL" width="100" height="100" /></a>A few months have passed and I did not release a new version of <strong>DeHL</strong> yet. No, it&#8217;s not dead. I&#8217;ve just been busy with a delicate new feature &#8212; <strong>Serialization</strong>. This post will demonstrate the new capabilities of DeHL it&#8217;s advantages and and shortcomings.</p>
<p>But first &#8212; since the new releases will focus mostly on serialization and related stuff, I decided to <strong>drop Delphi 2009 support</strong>. It made no sense to support 2009 for future versions since no essential changes are made to the prior code. You can still use 0.7 release in Delphi 2009.</p>
<p>Back to serialization. The following list describes the changes that went into the new version:</p>
<ul>
<li>In order to support serialization, DeHL&#8217;s type system was extended to support <span style="text-decoration: underline;">Serialize</span> and <span style="text-decoration: underline;">Deserialize</span> methods. Each type class (that describes a type in Delphi) now knows how to serialize values of the type it manages.</li>
<li>A new unit named <span style="text-decoration: underline;">DeHL.Serialization</span> was added. It contains the base definitions of types used by the type system for serialization.</li>
<li><span style="text-decoration: underline;">TPointerType</span>, <span style="text-decoration: underline;">TRecordType&lt;T&gt;</span>, <span style="text-decoration: underline;">TArrayType&lt;T&gt;</span>, etc. were added for simplified type handling. The old method was a mix-up of Delphi 2009 and Delphi 2010 RTTI specifics (which have some essential differences in my case).</li>
<li>All classes can now implement <span style="text-decoration: underline;">ISerializable</span> interface. The <span style="text-decoration: underline;">TClassType&lt;T&gt;</span> detects whether this interface is implemented by the object and uses it for serialization (no, reference counting is not touched).</li>
<li><strong>DeHL.Serialization.Abstract</strong> contains the semi-implementation of a &#8220;serializer&#8221; and it&#8217;s context. It is used by specific serializers.</li>
<li><strong>DeHL.Serialization.XML</strong> defines the <span style="text-decoration: underline;">TXMLSerializer&lt;T&gt;</span> which can be used to serialize/deserialize into XML nodes (uses TXMLDocument). Supports it&#8217;s own set of attributes (such as <em>XmlRoot</em>, <em>XmlElement</em>, etc.).</li>
<li><strong>DeHL.Serialization.Ini</strong> defines the <span style="text-decoration: underline;">TIniSerializer&lt;T&gt;</span> that you can use to serialize/deserialize type into Ini files or registry (through RTL&#8217;s <em>TRegIniFile</em>).</li>
<li>Most DeHL types (such as <em>Nullable&lt;T&gt;</em>,  <em>TFixedArray&lt;T&gt;</em>, <em>BigInteger</em>, etc.) provide their own serialization and deserialization methods.</li>
<li>All Enex collections (except a few that can&#8217;t actually) can be serialized and deserialized. They implement a custom serialization and deserialization technique through <span style="text-decoration: underline;">ISerializable</span>.</li>
</ul>
<p>Enough talk, a mandatory example:</p>
<pre class="brush: delphi">
type
  [XmlRoot(&#039;Testing&#039;, &#039;http://test.namespace.com&#039;)]
  TTest = class
    { Pointer to self }
    [XmlElement(&#039;PointerToSelf&#039;)]
    FSelf: TObject;
    {A set of format settings }
    FFormatSettings: TFormatSettings;

    { And internal record }
    FInternal: record
      { Force the field to be an attribute of FInternal }
      [XmlAttribute(&#039;Value&#039;)]
      FOne: Integer;

      { Force this element to have same name but other namespace }
      [XmlElement(&#039;Value&#039;, &#039;http://other.namespace.com&#039;)]
      FTwo: String;
    end;

    FListOfDoubles: TList&lt;Double&gt;;
  end;
var
  LDocument: IXMLDocument;
  LXMLSerializer: TXMLSerializer&lt;TTest&gt;;
  LOutInst, LInInst: TTest;
begin
  CoInitializeEx(nil, 0);

  { Initialize the test object }
  LOutInst := TTest.Create;
  LOutInst.FSelf := LOutInst;
  GetLocaleFormatSettings(GetThreadLocale(), LOutInst.FFormatSettings);
  LOutInst.FInternal.FOne := 1;
  LOutInst.FInternal.FTwo := &#039;2 - Two&#039;;
  LOutInst.FListOfDoubles := TList&lt;Double&gt;.Create();
  LOutInst.FListOfDoubles.Add(0.55);
  LOutInst.FListOfDoubles.Add(0.122);
  LOutInst.FListOfDoubles.Add(122.23);

  { Create the serializer and an XML document }
  LXMLSerializer := TXMLSerializer&lt;TTest&gt;.Create();
  LDocument := TXMLDocument.Create(nil);

  { Set the options }
  LDocument.Active := true;
  LDocument.Options := LDocument.Options + [doNodeAutoIndent];

  { Force fields to elements by default }
  LXMLSerializer.DefaultFieldsToTags := true;

  { Serialize the structure }
  LXMLSerializer.Serialize(LOutInst, LDocument.Node);

  { Serialize the structure }
  LXMLSerializer.Deserialize(LInInst, LDocument.Node);

  { Cleanup }
  LDocument.SaveToFile(&#039;c:\test.xml&#039;);
  LXMLSerializer.Free;
end.
</pre>
<p>The XML file generated by this code looks like this (INI looks uglier):</p>
<pre class="brush: xml">
&lt;Testing xmlns=&quot;http://test.namespace.com&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:DeHL=&quot;http://alex.ciobanu.org/DeHL.Serialization.XML&quot; xmlns:NS1=&quot;http://other.namespace.com&quot;&gt;
  &lt;PointerToSelf DeHL:ref=&quot;Testing&quot;/&gt;
  &lt;FFormatSettings&gt;
    &lt;CurrencyString&gt;$&lt;/CurrencyString&gt;
    &lt;CurrencyFormat&gt;0&lt;/CurrencyFormat&gt;
    &lt;CurrencyDecimals&gt;2&lt;/CurrencyDecimals&gt;
    &lt;DateSeparator&gt;/&lt;/DateSeparator&gt;
    &lt;TimeSeparator&gt;:&lt;/TimeSeparator&gt;
    &lt;ListSeparator&gt;,&lt;/ListSeparator&gt;
    &lt;ShortDateFormat&gt;M/d/yyyy&lt;/ShortDateFormat&gt;
    &lt;LongDateFormat&gt;dddd, MMMM dd, yyyy&lt;/LongDateFormat&gt;
    &lt;TimeAMString&gt;AM&lt;/TimeAMString&gt;
    &lt;TimePMString&gt;PM&lt;/TimePMString&gt;
    &lt;ShortTimeFormat&gt;h:mm AMPM&lt;/ShortTimeFormat&gt;
    &lt;LongTimeFormat&gt;h:mm:ss AMPM&lt;/LongTimeFormat&gt;
    &lt;ShortMonthNames&gt;
      &lt;string&gt;Jan&lt;/string&gt;
      &lt;string&gt;Feb&lt;/string&gt;
      &lt;string&gt;Mar&lt;/string&gt;
      &lt;string&gt;Apr&lt;/string&gt;
      &lt;string&gt;May&lt;/string&gt;
      &lt;string&gt;Jun&lt;/string&gt;
      &lt;string&gt;Jul&lt;/string&gt;
      &lt;string&gt;Aug&lt;/string&gt;
      &lt;string&gt;Sep&lt;/string&gt;
      &lt;string&gt;Oct&lt;/string&gt;
      &lt;string&gt;Nov&lt;/string&gt;
      &lt;string&gt;Dec&lt;/string&gt;
    &lt;/ShortMonthNames&gt;
    &lt;LongMonthNames&gt;
      &lt;string&gt;January&lt;/string&gt;
      &lt;string&gt;February&lt;/string&gt;
      &lt;string&gt;March&lt;/string&gt;
      &lt;string&gt;April&lt;/string&gt;
      &lt;string&gt;May&lt;/string&gt;
      &lt;string&gt;June&lt;/string&gt;
      &lt;string&gt;July&lt;/string&gt;
      &lt;string&gt;August&lt;/string&gt;
      &lt;string&gt;September&lt;/string&gt;
      &lt;string&gt;October&lt;/string&gt;
      &lt;string&gt;November&lt;/string&gt;
      &lt;string&gt;December&lt;/string&gt;
    &lt;/LongMonthNames&gt;
    &lt;ShortDayNames&gt;
      &lt;string&gt;Sun&lt;/string&gt;
      &lt;string&gt;Mon&lt;/string&gt;
      &lt;string&gt;Tue&lt;/string&gt;
      &lt;string&gt;Wed&lt;/string&gt;
      &lt;string&gt;Thu&lt;/string&gt;
      &lt;string&gt;Fri&lt;/string&gt;
      &lt;string&gt;Sat&lt;/string&gt;
    &lt;/ShortDayNames&gt;
    &lt;LongDayNames&gt;
      &lt;string&gt;Sunday&lt;/string&gt;
      &lt;string&gt;Monday&lt;/string&gt;
      &lt;string&gt;Tuesday&lt;/string&gt;
      &lt;string&gt;Wednesday&lt;/string&gt;
      &lt;string&gt;Thursday&lt;/string&gt;
      &lt;string&gt;Friday&lt;/string&gt;
      &lt;string&gt;Saturday&lt;/string&gt;
    &lt;/LongDayNames&gt;
    &lt;ThousandSeparator&gt;,&lt;/ThousandSeparator&gt;
    &lt;DecimalSeparator&gt;.&lt;/DecimalSeparator&gt;
    &lt;TwoDigitYearCenturyWindow&gt;50&lt;/TwoDigitYearCenturyWindow&gt;
    &lt;NegCurrFormat&gt;0&lt;/NegCurrFormat&gt;
  &lt;/FFormatSettings&gt;
  &lt;FInternal Value=&quot;1&quot;&gt;
    &lt;NS1:Value&gt;2 - Two&lt;/NS1:Value&gt;
  &lt;/FInternal&gt;
  &lt;FListOfDoubles&gt;
    &lt;Elements&gt;
      &lt;Double&gt;0.55&lt;/Double&gt;
      &lt;Double&gt;0.122&lt;/Double&gt;
      &lt;Double&gt;122.23&lt;/Double&gt;
    &lt;/Elements&gt;
  &lt;/FListOfDoubles&gt;
&lt;/Testing&gt;
</pre>
<p>On the first serialized/deserialized value, serializers build up a sort of an internal &#8220;object graph&#8221; and gathers all information about the data being serialized. The next uses of the same serializer instance yield an 10x performance gain since there is no need to rebuild all the information from scratch. I am still working on more optimizations that could give greater speed boost.</p>
<p>P.S. I can&#8217;t show the contents of the deserialized object here so you&#8217;ll have to take my word for it.</p>
<p><span style="color: #ff0000;"><strong>Note. This is just a preview of what is going on in the trunk. No version is released since I have to iron out the last problems and write the missing unit tests.</strong></span></p>
<p>﻿﻿﻿﻿﻿﻿﻿</p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=285</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>TypeInfo workaround</title>
		<link>http://alex.ciobanu.org/?p=270</link>
		<comments>http://alex.ciobanu.org/?p=270#comments</comments>
		<pubDate>Sun, 11 Oct 2009 13:29:49 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[delphi_12_specific]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[RTL]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=270</guid>
		<description><![CDATA[This is going to be a short one. Just wanted to share a simple and elegant work-around for this QC issue: type TypeOf&#60;T&#62; = record class function TypeInfo: PTypeInfo; static; class function Name: string; static; class function Kind: TTypeKind; static; end; { TypeOf&#60;T&#62; } class function TypeOf&#60;T&#62;.Kind: TTypeKind; var LTypeInfo: PTypeInfo; begin LTypeInfo := TypeInfo; [...]]]></description>
			<content:encoded><![CDATA[<p>This is going to be a short one. Just wanted to share a simple and elegant work-around for <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=78112">this QC</a> issue:</p>
<pre class="brush: delphi">
type
  TypeOf&lt;T&gt; = record
    class function TypeInfo: PTypeInfo; static;
    class function Name: string; static;
    class function Kind: TTypeKind; static;
  end;

{ TypeOf&lt;T&gt; }

class function TypeOf&lt;T&gt;.Kind: TTypeKind;
var
  LTypeInfo: PTypeInfo;
begin
  LTypeInfo := TypeInfo;

  if LTypeInfo &lt;&gt; nil then
    Result := LTypeInfo^.Kind
  else
    Result := tkUnknown;
end;

class function TypeOf&lt;T&gt;.Name: string;
var
  LTypeInfo: PTypeInfo;
begin
  LTypeInfo := TypeInfo;

  if LTypeInfo &lt;&gt; nil then
    Result := GetTypeName(LTypeInfo)
  else
    Result := &#039;&#039;;
end;

class function TypeOf&lt;T&gt;.TypeInfo: PTypeInfo;
begin
  Result := System.TypeInfo(T);
end;
</pre>
<p>Now, you can obtain the type information for any type by simply using <i>TypeOf&lt;T&gt;.TypeInfo</i>:</p>
<pre class="brush: delphi">
type
  TRecord&lt;T&gt; = record
    FVal: T;
  end;

  TIntRecord = TRecord&lt;Integer&gt;;

begin
  // TypeInfo(TIntRecord); // Fails with compile-time error;
  WriteLn(GetTypeName(TypeOf&lt;TIntRecord&gt;.TypeInfo));

  ReadLn;
end.
</pre>
<p>You can also use this construct to obtain the type information for generic types from within themselves:</p>
<pre class="brush: delphi">
type
  TSomeRec&lt;T&gt; = record
    function GetMyName: String;
  end;

function TSomeRec&lt;T&gt;.GetMyName(): String;
begin
  // Result := GetTypeName(TypeInfo(TSomeRec&lt;T&gt;)); // Fails
  Result := TypeOf&lt;TSomeRec&lt;T&gt;&gt;.Name;
end;
</pre>
<p>The only thing to notice is that compile time <strong>[DCC Error] E2134 Type &#8216;XXX&#8217; has no type info</strong> errors will not be triggered for types having no type info. Instead, the <i>TypeOf&lt;T&gt;.TypeInfo</i> method will return <i>nil</i>.</p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=270</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DeHL 0.7 is up</title>
		<link>http://alex.ciobanu.org/?p=263</link>
		<comments>http://alex.ciobanu.org/?p=263#comments</comments>
		<pubDate>Fri, 02 Oct 2009 09:56:23 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[BSD]]></category>
		<category><![CDATA[DeHL]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[RTL]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=263</guid>
		<description><![CDATA[After a few months of no releases, I finally decided to throw one out &#8212; so here it is, DeHL 0.7. This release is adding three more collection, new types and fixes some internal limitations of the library. For the people that never tried DeHL &#8211; it is a collection of types and classes that [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-242" href="http://alex.ciobanu.org/?attachment_id=242"><img class="alignleft size-full wp-image-242" title="DeHL" src="http://alex.ciobanu.org/files/uploads/2009/06/Logo_2.png" alt="DeHL" width="100" height="100" /></a></p>
<p>After a few months of no releases, I finally decided to throw one out &#8212; so here it is, <a href="http://delphilhlplib.googlecode.com/files/DeHL_0.7.0.zip">DeHL 0.7</a>. This release is adding three more collection, new types and fixes some internal limitations of the library.</p>
<p>For the people that never tried DeHL &#8211; it is a collection of types and classes that use (<span style="text-decoration: underline;">and even abuse</span>) the newer generation Delphi compilers into obtaining some features that were impossible in the past releases.</p>
<h3>The newly added collection classes are:</h3>
<ul>
<li><em>TPriorityQueue&lt;TPriority, TValue&gt;</em> which implements the priority queue.</li>
<li><em>TDistinctMultiMap&lt;TKey, TValue&gt;</em> that is similar to <em>TMultiMap</em> but uses sets instead of lists to store the values. This ensures that all values for a key are distinct. As usual 2 more flavors of this class exist &#8211; <em>TSortedDistinctMultiMap&lt;TKey, TValue&gt;</em> and <em>TDoubleSortedDistinctMultiMap&lt;TKey, TValue&gt;.</em></li>
<li><em>TBidiMap&lt;TKey, TValue&gt;</em> implements the concept of bi-directional map in which there is a bi-directional relation between keys and values (both are actually keys). <em>TSortedBidiMap&lt;TKey, TValue&gt;</em> and <em>TDoubleSortedBidiMap&lt;TKey, TValue&gt;</em> are the other two flavors of this class.</li>
<li><em>TStringList&lt;T&gt;</em> and <em>TWideStringList&lt;T&gt;</em> collections are actually generic variants of the normal <em>TStringList</em> and <em>TWideStringList</em> (which are used as base classes).</li>
</ul>
<h3>Other enhancements include:</h3>
<ul>
<li><em>Singleton&lt;T&gt;</em> class. Which can be used to access the same instance of a class across all application.</li>
<li><em>TWideCharSet</em> (this was inspired on other implementations out there but use dynamic arrays to save memory and speed in certain circumstances).</li>
<li><em>TType</em> speed and reliability increases.</li>
<li>A global <em>DeHL.Defines.inc</em> files for all $IFDEF needs.</li>
<li>Types such as <em>Nullable&lt;T&gt;</em>, <em>Scoped&lt;T&gt;</em> and <em>TKeyValuePair&lt;TKey, TValue</em>&gt; now have their own type classes.</li>
</ul>
<p>For a full list of changes see the <a href="http://code.google.com/p/delphilhlplib/source/browse/tags/0.7/changelog.txt">changelog</a>.</p>
<p>This release also makes use of some new improvements of the <strong>Delphi 2010</strong> compiler (such as class constructors, or some fixed problems in the generics handling) which makes some features unavailable on Delphi 2009. I plan to keep Delphi 2009 supported for as long as possible, but many new planned features are not going to be available on that platform.</p>
<p><strong>Have Fun!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=263</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Class constructors and Generics</title>
		<link>http://alex.ciobanu.org/?p=258</link>
		<comments>http://alex.ciobanu.org/?p=258#comments</comments>
		<pubDate>Sun, 13 Sep 2009 10:39:32 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[Help]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[RTL]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=258</guid>
		<description><![CDATA[The new great addition to the Delphi language in Delphi 2010 is the possibility to specify a class constructor and a class destructor to your class/record. I will not describe this feature in this post since you can see the online documentation for it on the Embarcadero Doc Wiki. The part I am interested in [...]]]></description>
			<content:encoded><![CDATA[<p>The new great addition to the Delphi language in <strong>Delphi 2010</strong> is the possibility to specify a <a href="http://docwiki.embarcadero.com/RADStudio/en/Methods#Class_Constructors">class constructor</a> and a <a href="http://docwiki.embarcadero.com/RADStudio/en/Methods#Class_Destructors">class destructor</a> to your class/record. I will not describe this feature in this post since you can see the online documentation for it on the<em> Embarcadero Doc Wiki</em>. The part I am interested in is the combination of class constructors and generics. As you might already know generic types aren&#8217;t really &#8220;run-time entities&#8221; but rather &#8220;compile-time&#8221; ones. This makes the initialization of &#8220;static&#8221; members of the type a bit more complicated. See for example this record:</p>
<pre class="brush: delphi">
type
  TMyType&lt;T&gt; = record
  private class var
    FSomeList: TList&lt;T&gt;;

  public
    ...
    ...
  end;
</pre>
<p>In this case the static <strong>FSomeList</strong> variable needs to be initialized to make sense. Normally, in non-generic classes, you would use the &#8220;<em>initialization</em>&#8221; and &#8220;<em>finalization</em>&#8221; sections to create and then destroy that variable. In generic classes this is impossible though. You have to get some workarounds (like initializing the list lazily), but you still cannot destroy the list on finalization.</p>
<p><strong>Well, not anymore!</strong> Using class constructors and destructors allows you to easily initialize any static member of a type:</p>
<pre class="brush: delphi">
type
  TMyType&lt;T&gt; = record
  private class var
    FSomeList: TList&lt;T&gt;;

    class constructor Create;
    class destructor Destroy;
  public
    ...
    ...
  end;

class constructor TMyType&lt;T&gt;.Create;
begin
  // Executed on application initialization.
  FSomeList := TList&lt;T&gt;.Create();
end;

class destructor TMyType&lt;T&gt;.Destroy;
begin
  // Freed on application termination.
  FSomeList.Free;
end;
</pre>
<p><strong>There is a catch tough.</strong> Since generic types are compile-time entities, any unit that uses a specialized generic type basically defines that type in itself. For example if you use <em>TList&lt;String&gt;</em> in four of your units, all four units will internally declare the <em>TList&lt;String&gt;</em> class. This results in the <em>TList&lt;T&gt;</em>&#8216;s class constructor to be executed four times &#8211; once per unit. This is expected behavior since each type specialization has different static members. For example:</p>
<pre class="brush: delphi">
type
  TDistinctType&lt;T&gt; = record
  private class var
    FMarker: Integer;

    class constructor Create;
  end;
</pre>
<p>If <em>TDistinctType&lt;String&gt;</em> is used in multiple units, each unit&#8217;s version has it own FMarker, which means it needs to be initialized for each unit.</p>
<p><strong>The conclusion &#8212; be aware that class constructors and destructors for generic types may execute multiple times.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=258</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>DeHL 0.6 available</title>
		<link>http://alex.ciobanu.org/?p=241</link>
		<comments>http://alex.ciobanu.org/?p=241#comments</comments>
		<pubDate>Sun, 21 Jun 2009 16:58:57 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[DeHL]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[delphi_12_specific]]></category>
		<category><![CDATA[EMBT]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[RTL]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://alex.ciobanu.org/?p=241</guid>
		<description><![CDATA[Yes I know I have skipped 0.5. The reality is that 0.5 was due a long time ago, but I did not have enough free time on my hands to complete the unit testing for all new features added. I always try to add as many unit tests as possible to test all possible scenarios. [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-242" href="http://alex.ciobanu.org/?attachment_id=242"><img class="alignleft size-full wp-image-242" title="DeHL" src="http://alex.ciobanu.org/files/uploads/2009/06/Logo_2.png" alt="DeHL" width="100" height="100" /></a></p>
<p>Yes I know I have skipped 0.5. The reality is that 0.5 was due a long time ago, but I did not have enough free time on my hands to complete the unit testing for all new features added. I always try to add as many unit tests as possible to test all possible scenarios.</p>
<p>This release features a general reorganization of some key concepts, new type extension mechanics, boxing, a lot more collections, better support for associative collections through specific Enex extensions &#8230; and many more. I am not going to lay out all the changes here since there are quite a few of them. You can view the change log <a href="http://delphilhlplib.googlecode.com/svn/tags/0.6/changelog.0.6.txt">here</a>.</p>
<p>One important note, check out the <strong>DeHL.Base.pas</strong> unit. There are a number of <strong>TOGGLE_XXXXX</strong> constants. Toggle them to <em>true</em> or <em>false</em> (if you are using Weaver FT builds) to enable or disable specific functionality. In Tiburon (Delphi 2009) all the features are disabled by default (to be on the safe side).</p>
<p>Get the latest build <a href="http://code.google.com/p/delphilhlplib/downloads/list">here</a>. If you stumble upon some bugs please report them <a href="http://code.google.com/p/delphilhlplib/issues/list">here</a>.</p>
<p><strong>Have Fun!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://alex.ciobanu.org/?feed=rss2&amp;p=241</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
