<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Class Helpers &#8211; Ruling from the Appellate Court</title>
	<atom:link href="http://www.deltics.co.nz/blog/?feed=rss2&#038;p=282" rel="self" type="application/rss+xml" />
	<link>http://www.deltics.co.nz/blog/?p=282</link>
	<description>Keeping Pascal afloat in Aotearoa</description>
	<lastBuildDate>Tue, 18 Jun 2013 21:24:49 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
	<item>
		<title>By: Jolyon Smith</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-174</link>
		<dc:creator>Jolyon Smith</dc:creator>
		<pubDate>Tue, 02 Sep 2008 07:34:31 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-174</guid>
		<description><![CDATA[@Lachlan

Yes, the chances of running into problems with a /CodeGear/ helper are minimal.

But the chances of running into a helper for a CodeGear class in someone else&#039;s code will increase if more and more people start to feel comfortable using them.

Keld is not the only person to have struck on the idea of a TStream helper, for example.

People obviously won&#039;t create helpers for their *own* classes - they can just modify their own classes (the need that CodeGear had was pretty unique).

But the VCL is the single most significant, if not largest, common codebase that all Delphi developers have in common and is the codebase that helpers are most likely to be created for.

If everyone starts helping themselves to classes in the VCL, their ability to share code with other Delphi developers is subject to an unnecessary and avoidable risk.


I am increasingly convinced that the name is the biggest problem with class helpers.  Anything that &quot;helps&quot; has got to be good, right?

If they had been called &quot;class patchers&quot; or &quot;class customizations&quot; I don&#039;t think people would be in nearly so much of a hurry to expose themselves to them.

:)

But if you never share code with/from anyone else and never will, no worries.]]></description>
		<content:encoded><![CDATA[<p>@Lachlan</p>
<p>Yes, the chances of running into problems with a /CodeGear/ helper are minimal.</p>
<p>But the chances of running into a helper for a CodeGear class in someone else&#8217;s code will increase if more and more people start to feel comfortable using them.</p>
<p>Keld is not the only person to have struck on the idea of a TStream helper, for example.</p>
<p>People obviously won&#8217;t create helpers for their *own* classes &#8211; they can just modify their own classes (the need that CodeGear had was pretty unique).</p>
<p>But the VCL is the single most significant, if not largest, common codebase that all Delphi developers have in common and is the codebase that helpers are most likely to be created for.</p>
<p>If everyone starts helping themselves to classes in the VCL, their ability to share code with other Delphi developers is subject to an unnecessary and avoidable risk.</p>
<p>I am increasingly convinced that the name is the biggest problem with class helpers.  Anything that &#8220;helps&#8221; has got to be good, right?</p>
<p>If they had been called &#8220;class patchers&#8221; or &#8220;class customizations&#8221; I don&#8217;t think people would be in nearly so much of a hurry to expose themselves to them.</p>
<p> <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>But if you never share code with/from anyone else and never will, no worries.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jolyon Smith</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-173</link>
		<dc:creator>Jolyon Smith</dc:creator>
		<pubDate>Tue, 02 Sep 2008 07:22:13 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-173</guid>
		<description><![CDATA[@Allen

I think you identified the difference yourself.  In any other case you can qualify to make the desired scope explicit - something that isn&#039;t possible with class helpers (without adjusting unit order in the uses list).

The other difference is that whilst it may be possible to accidentally run into this situation even without class helpers, here was a suggestion that we deliberately *create* a possible breaking change as a way to work around a different possible breaking change.  The methods were specifically devised to have different behaviours but identical signatures to give the illusion of a method from the base helper propogating into the derived helper but with different behaviour - simulating a virtual method in a way.

Yes, such collisions can arise in other cases, but is less likely - certainly not impossible, but definitely less likely than a *deliberately* crafted situation.  imho.



@Keld

There IS a difference between scope affecting helpers and scope effects in OO hierarchies generally - see Allen&#039;s comment and my reply to him, above .

Your questions about why CodeGear did not implement warnings etc can of course only be answered by CodeGear.

Although one might speculate that there is little point in implementing compiler support for warnings for a feature that people shouldn&#039;t be using if they are paying attention to the warnings in the documentation.... maybe?

Even if the compiler were warning you, I suspect you would just be suppressing/ignoring those warnings anyway?

;)



As for what happened with your comment, I&#039;m not entirely sure.

Did you post comments from different machines or using a different email address?  Ordinarily once a comment has been approved then the system seems to accept all comments from that author without requiring separate approval for each one, but I haven&#039;t looked into how non-registered visitor comments are associated with a particular author (by email?  IP address).  Mostly WordPress &quot;just works&quot; well enough for me - I&#039;m by no means an expert on it though.

On the other hand it&#039;s possible I might have just missed it - it was a late night after a long (and frankly tedious) day at Tech Ed and I had two browsers open on my blog doing different things simultaneously.

It certainly wasn&#039;t deliberate.

In future however I think I would ask that if you have detailed discussion points, I would prefer you to email them.  If nothing else having to maintain the thread of a conversation in a comment stream is awkward.

If an email discussion leads to useful follow-up content, I will post it separately, even if it involves my changing my mind on some subject.  In fact, even more assuredly so in that case.

That  is not going to happen in this case though.

:)]]></description>
		<content:encoded><![CDATA[<p>@Allen</p>
<p>I think you identified the difference yourself.  In any other case you can qualify to make the desired scope explicit &#8211; something that isn&#8217;t possible with class helpers (without adjusting unit order in the uses list).</p>
<p>The other difference is that whilst it may be possible to accidentally run into this situation even without class helpers, here was a suggestion that we deliberately *create* a possible breaking change as a way to work around a different possible breaking change.  The methods were specifically devised to have different behaviours but identical signatures to give the illusion of a method from the base helper propogating into the derived helper but with different behaviour &#8211; simulating a virtual method in a way.</p>
<p>Yes, such collisions can arise in other cases, but is less likely &#8211; certainly not impossible, but definitely less likely than a *deliberately* crafted situation.  imho.</p>
<p>@Keld</p>
<p>There IS a difference between scope affecting helpers and scope effects in OO hierarchies generally &#8211; see Allen&#8217;s comment and my reply to him, above .</p>
<p>Your questions about why CodeGear did not implement warnings etc can of course only be answered by CodeGear.</p>
<p>Although one might speculate that there is little point in implementing compiler support for warnings for a feature that people shouldn&#8217;t be using if they are paying attention to the warnings in the documentation&#8230;. maybe?</p>
<p>Even if the compiler were warning you, I suspect you would just be suppressing/ignoring those warnings anyway?</p>
<p> <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>As for what happened with your comment, I&#8217;m not entirely sure.</p>
<p>Did you post comments from different machines or using a different email address?  Ordinarily once a comment has been approved then the system seems to accept all comments from that author without requiring separate approval for each one, but I haven&#8217;t looked into how non-registered visitor comments are associated with a particular author (by email?  IP address).  Mostly WordPress &#8220;just works&#8221; well enough for me &#8211; I&#8217;m by no means an expert on it though.</p>
<p>On the other hand it&#8217;s possible I might have just missed it &#8211; it was a late night after a long (and frankly tedious) day at Tech Ed and I had two browsers open on my blog doing different things simultaneously.</p>
<p>It certainly wasn&#8217;t deliberate.</p>
<p>In future however I think I would ask that if you have detailed discussion points, I would prefer you to email them.  If nothing else having to maintain the thread of a conversation in a comment stream is awkward.</p>
<p>If an email discussion leads to useful follow-up content, I will post it separately, even if it involves my changing my mind on some subject.  In fact, even more assuredly so in that case.</p>
<p>That  is not going to happen in this case though.</p>
<p> <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Keld R. Hansen</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-172</link>
		<dc:creator>Keld R. Hansen</dc:creator>
		<pubDate>Mon, 01 Sep 2008 16:31:03 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-172</guid>
		<description><![CDATA[Oh, and one question to you, Jolyon:

Why is my comment from 02:00am &quot;awaiting moderation&quot; when my comments at 04:28am and this one aren&#039;t?]]></description>
		<content:encoded><![CDATA[<p>Oh, and one question to you, Jolyon:</p>
<p>Why is my comment from 02:00am &#8220;awaiting moderation&#8221; when my comments at 04:28am and this one aren&#8217;t?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Keld R. Hansen</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-171</link>
		<dc:creator>Keld R. Hansen</dc:creator>
		<pubDate>Mon, 01 Sep 2008 16:28:04 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-171</guid>
		<description><![CDATA[@Allen:

Thank you for joining the discussion. It&#039;s always nice to get some information straight &quot;from the horse&#039;s mouth&quot; (not that you are a horse :)).

A couple of questions I have in this discussion, could possibly be clarified by you:

1) Why was the CLASS HELPER ported to Delphi 2005 Win32 in the first place? At that time, CodeGear had no need for it (at least no need that I am aware of).

2) Why was CLASS HELPER inheritance allowed? As far as I know, CodeGear doesn&#039;t use it, so if CLASS HELPERs were *only* intented for use by CodeGear, why implement a feature that CodeGear doesn&#039;t need?

3) Why - if CodeGear wants to discourage its use - doesn&#039;t the compiler issue a warning when encountering a CLASS HELPER definition?

4) Was the warning that is now present in Delphi 2007 Help already present in the Delphi 2005 Help?

And, finally, a question that you probably can&#039;t/won&#039;t answer :):

Are CodeGear planning to extend the CLASS HELPER support in Win32 to the point where the pitfalls we have discussed here will be addressed, or are CodeGear playing with the idea to remove them altogether from the Win32 compiler?]]></description>
		<content:encoded><![CDATA[<p>@Allen:</p>
<p>Thank you for joining the discussion. It&#8217;s always nice to get some information straight &#8220;from the horse&#8217;s mouth&#8221; (not that you are a horse <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).</p>
<p>A couple of questions I have in this discussion, could possibly be clarified by you:</p>
<p>1) Why was the CLASS HELPER ported to Delphi 2005 Win32 in the first place? At that time, CodeGear had no need for it (at least no need that I am aware of).</p>
<p>2) Why was CLASS HELPER inheritance allowed? As far as I know, CodeGear doesn&#8217;t use it, so if CLASS HELPERs were *only* intented for use by CodeGear, why implement a feature that CodeGear doesn&#8217;t need?</p>
<p>3) Why &#8211; if CodeGear wants to discourage its use &#8211; doesn&#8217;t the compiler issue a warning when encountering a CLASS HELPER definition?</p>
<p>4) Was the warning that is now present in Delphi 2007 Help already present in the Delphi 2005 Help?</p>
<p>And, finally, a question that you probably can&#8217;t/won&#8217;t answer <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> :</p>
<p>Are CodeGear planning to extend the CLASS HELPER support in Win32 to the point where the pitfalls we have discussed here will be addressed, or are CodeGear playing with the idea to remove them altogether from the Win32 compiler?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Allen Bauer</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-170</link>
		<dc:creator>Allen Bauer</dc:creator>
		<pubDate>Mon, 01 Sep 2008 15:52:29 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-170</guid>
		<description><![CDATA[&quot;So let me see, depending on which class helper is “visible”, then this line of code:

ComboBox.Add(”);

could do two entirely different things? And simply changing the order of your uses list could change that behaviour?

And you are offering this to support an argument in FAVOUR of class helpers?

Hmmmmmmm.&quot;

I&#039;m not trying to be pedantic or obtuse here, but how is that different than normal Pascal scoping rules? Suppose Unit A and Unit B both have a global function Foo: Integer; Depending on the order that those units appear, either the Unit A version or the Unit B version would be called. The same thing happens with types or all interfaced symbols. So Units A &amp; B both define a type X, and depending upon the order of usage, code would refer to one or the other. You can even &quot;override&quot; the meaning of &quot;Integer&quot; by defining your own symbol.

I guess the one difference would be that you can always fully qualify the symbol with the unit name to get around this &quot;problem.&quot; However, this &quot;problem&quot; has long been considered a language feature.

&#039;5) the lack of runtime support is not considered a bug - it is “As Designed”&#039;

As you assert, this feature was implemented to the point that it served CodeGear&#039;s purpose. As of right now, in Delphi/Win32, non-virtual methods are the only &quot;safe&quot; kinds of methods to add.  Delphi/.NET got a more complete implementation because we needed a more complete implementation for .NET.

Allen.]]></description>
		<content:encoded><![CDATA[<p>&#8220;So let me see, depending on which class helper is “visible”, then this line of code:</p>
<p>ComboBox.Add(”);</p>
<p>could do two entirely different things? And simply changing the order of your uses list could change that behaviour?</p>
<p>And you are offering this to support an argument in FAVOUR of class helpers?</p>
<p>Hmmmmmmm.&#8221;</p>
<p>I&#8217;m not trying to be pedantic or obtuse here, but how is that different than normal Pascal scoping rules? Suppose Unit A and Unit B both have a global function Foo: Integer; Depending on the order that those units appear, either the Unit A version or the Unit B version would be called. The same thing happens with types or all interfaced symbols. So Units A &amp; B both define a type X, and depending upon the order of usage, code would refer to one or the other. You can even &#8220;override&#8221; the meaning of &#8220;Integer&#8221; by defining your own symbol.</p>
<p>I guess the one difference would be that you can always fully qualify the symbol with the unit name to get around this &#8220;problem.&#8221; However, this &#8220;problem&#8221; has long been considered a language feature.</p>
<p>&#8217;5) the lack of runtime support is not considered a bug &#8211; it is “As Designed”&#8217;</p>
<p>As you assert, this feature was implemented to the point that it served CodeGear&#8217;s purpose. As of right now, in Delphi/Win32, non-virtual methods are the only &#8220;safe&#8221; kinds of methods to add.  Delphi/.NET got a more complete implementation because we needed a more complete implementation for .NET.</p>
<p>Allen.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Lachlan Gemmell</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-169</link>
		<dc:creator>Lachlan Gemmell</dc:creator>
		<pubDate>Mon, 01 Sep 2008 14:31:47 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-169</guid>
		<description><![CDATA[If you do a search on the Delphi 2007 VCL (excluding the VCL.NET) source code you&#039;ll find only 2 instances in which class helpers are used. I&#039;m assuming that since Delphi 2009 will be a breaking release both of these instances will disappear with the additional methods being added into the respective classes proper.

Since CodeGear makes such limited use of the class helper feature the chance of running into side effects resulting from duplicate class helpers are extremely minimal.

If you&#039;re using class helpers, which I do,  the burden is on you to search the VCL and any third party code to make sure that you aren&#039;t conflicting with their potential usage of class helpers. Chances are though that you won&#039;t be, but you must check!!!]]></description>
		<content:encoded><![CDATA[<p>If you do a search on the Delphi 2007 VCL (excluding the VCL.NET) source code you&#8217;ll find only 2 instances in which class helpers are used. I&#8217;m assuming that since Delphi 2009 will be a breaking release both of these instances will disappear with the additional methods being added into the respective classes proper.</p>
<p>Since CodeGear makes such limited use of the class helper feature the chance of running into side effects resulting from duplicate class helpers are extremely minimal.</p>
<p>If you&#8217;re using class helpers, which I do,  the burden is on you to search the VCL and any third party code to make sure that you aren&#8217;t conflicting with their potential usage of class helpers. Chances are though that you won&#8217;t be, but you must check!!!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Keld R. Hansen</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-168</link>
		<dc:creator>Keld R. Hansen</dc:creator>
		<pubDate>Mon, 01 Sep 2008 14:00:07 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-168</guid>
		<description><![CDATA[You wrote:

So let me see, depending on which class helper is “visible”, then this line of code:

ComboBox.Add(”);

could do two entirely different things? And simply changing the order of your uses list could change that behaviour?

My reply:

Yes - but so could any OO hieararchy using inheritance - there&#039;s no difference there...

You wrote:

Yes, name collisions occur with inheritance, but there are legitimate and reliable mechanisms for dealing with those.

My reply:

So are there for Class Helpers :).

You wrote:

Most typically if you have a method in a base class that has the same name in a derived class it is normally because that method is polymorphic - it will be virtual in the base class and overridden in the derived class.

My reply:

Yes - that&#039;s the &quot;typical&quot; way, but even with inheritance, you can hit problems if you have written a descendant class for which the parent class suddenly is changed (which in essense if what you do with class helpers - modify the parent class, but without impacting code that aren&#039;t using your extensions).

You wrote:

I would say “Try that with a class helper” but I wouldn’t want to waste your time, so instead simply read this:

http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/

My reply:

I *have* read it, and have yet to need virtual methods in class helpers, since the way I use them mainly is to OO&#039;ize old-style procedural-calls.

Like I said yesterday, I don&#039;t expect to use Class Helpers to implement advanced routines, but for the simple extensions I am using them (like my TStream example yesterday), I find them extremely useful.

You wrote:

Can you “reintroduce” with a class helper?

Even if you can, you do not get the same behaviour that you would get with a regular class since you cannot qualify using a class helper name so there is no way to get at the hidden method as you can with an OO, but non-polymorphic, class - your derived helper would permanently and unavoidably deny access to any inherited method with the same signature (overloads will - I should say “might” - allow methods that differ in parameters alone to propogate into the derived helper).

My reply:

If I f.ex. introduce a method with identical sugnature in a class helper for TComboBox, I can call the original TComboBox method in one of two ways:

1) Introduce a wrapper call in my class helper (as illustrated in my example today). By marking it INLINE, I can even eliminate any code overhead.

2) If the call really originates in a parent to TComboBox, I can cast my variable to that parent (TCustomComboBox) in order to &quot;escape&quot; the class helper.

You wrote:

And worse - as your own example demonstrated quite nicely - you risk having code that could inadvertently change behaviour in response to a simple change the order of units in a uses list.

My reply:

What&#039;s the difference in this and any other naming conflict you can encounter by having two libraries both defining a class TExtDialog, f.ex.? You could run into the exact same problem there, but I don&#039;t see you objecting to normal class inheritance or ordinary OO programming :).

You wrote:

This makes perfect sense if you remember that they were designed for CODEGEAR to use “internally” so only had to suit the purposes to which CodeGear intended to put them, and that was to address a cross-platform issue between VCL and VCL.NET code.

My reply:

But then, why did CodeGear

1) Allow the syntax in Delphi Win32?

2) Allow Class Helper inheritance

3) Not make the compiler issue a warning, like it does with so many other things (deprecated, platform specific, hides earlier implementation, etc. etc.)?

You wrote:

if I understand correctly, they are used in D2007 primarily to avoid a breaking change between D2006 and D2007 - I doubt there will be any class helpers in the Delphi 2009 VCL source as this will be a breaking release so such temporary fixes are not needed.

My reply:

But then:

1) Why was Class Helpers (buggy) supported even in Delphi 2005?

2) Why was Class Helpers (fixed) supported even in Delphi 2006?

In other words - Class Helpers were NOT implemented in Delphi 2007 for Win32 to allow this non-breaking release. It&#039;s the other way around - the non-breaking release TOOK ADVANTAGE of already existing Class Helper support in order to make the release non-breaking.

You wrote:

“But they are documented, so we are clearly supposed to use them” (paraphrase)

1) this ignores the fact that the same documentation being held up as validation their use contains a warning specifically suggesting that you do not.

Do we trust the documentation as an authority, or dismiss it as irrelevant? You seem to want to do both.

My reply:

I can&#039;t remember I have ever seen that warning. I just tried it on my Delphi 2007, and there&#039;s a warning there, but I can&#039;t recall ever seeing that warning in neither Delphi 2005 nor Delphi 2006. So to my mind, the warning is an after-rationalization that they have come up with post-haste to try to put the cat back in the bag. Unfortunately, they are too late - the cat&#039;s already out of the bag, all the way back from Delphi 2005 (where I started using them).

You wrote:

2) if the VCL source were not published there would have been no need to even mention class helpers, let alone document them. But since class helpers were inevitably going to be “on view” they had to be documented. Even without documentation someone would have found them in the VCL source, figured out how to use them and then excitedly told everyone the secret they had discovered.

My reply:

But why document them FULLY. Why not just - from the very onset (Delphi 2005) - state in the help file:

Class Helpers are an internal feature used by CodeGear to allow interface between .NET and VCL and is not to be used by other people.

and nothing more? And why - in the first place - port it to Win32, if it wasn&#039;t that we were supposed to use them (and no - it wasn&#039;t ported to Win32 to allow the non-breaking release of Delphi 2007, since they were there all the way back in Delphi 2005).

You wrote:

“They could yet implement them fully?”

Indeed they could, but why should they?

My reply:

Because it&#039;s a NICE feature that allows me (and others) to implement small snippets of code into the VCL hieararchy without the need to re-compile it (and thus break compatibility with old code).

Yes - there are some problems and pitfalls with the specific implementation, but that could probably be solved in various ways - least of all are compiler warnings, where a class helper introduces methods that override or conflicts with existing names, and/or warnings where there&#039;s a possibility for ambiguity in the use of a class helper (no need to warn about TStreamHelper.WriteInteger unless there&#039;s a descendant or parent class that also has a WriteInteger with the same signature).

One could even allow these warnings to be promoted to errors on a project-by-project basis to force the programmers to resolve any ambiguity before allowing the program to compile.

You wrote:

CodeGear have - from the outset - told us that we should not be using them.

My reply:

Like I said, that&#039;s a statement I don&#039;t believe is true. I&#039;ll try to see if I can find my old, dusty Delphi 2005 compiler and see if the warning is there in the help file all the way back then, but I don&#039;t remember ever reading a warning about it in any help file until I today looked it up in Delphi 2007.

You wrote:

1) the documentation suggests, quite directly and really quite strongly, that class helpers are something that should not be used

My reply:

Yes - at least in Delphi 2007. Whether or not it was there in the Delphi 2005 documentation remains to be seen...

You wrote:

Yet despite all this, you believe that I am wrong to suggest that it would be sensible, at the very least, to heed that warning at #1, above.

My reply:

If by &quot;heed that warning&quot; you mean &quot;don&#039;t EVER use class helpers&quot;, then, yes, I think you are wrong. Like any tool, class helpers can be mis-used, but if one is aware of the pitfalls, I don&#039;t see anything wrong with using them.

If they are used (as I do) to make code more readable and maintainable, then I am all for it. Use the tools that you have available, but use them responsibly...

Should cars be illegal because they can kill people? :) How about a power drill? ;).]]></description>
		<content:encoded><![CDATA[<p>You wrote:</p>
<p>So let me see, depending on which class helper is “visible”, then this line of code:</p>
<p>ComboBox.Add(”);</p>
<p>could do two entirely different things? And simply changing the order of your uses list could change that behaviour?</p>
<p>My reply:</p>
<p>Yes &#8211; but so could any OO hieararchy using inheritance &#8211; there&#8217;s no difference there&#8230;</p>
<p>You wrote:</p>
<p>Yes, name collisions occur with inheritance, but there are legitimate and reliable mechanisms for dealing with those.</p>
<p>My reply:</p>
<p>So are there for Class Helpers <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>You wrote:</p>
<p>Most typically if you have a method in a base class that has the same name in a derived class it is normally because that method is polymorphic &#8211; it will be virtual in the base class and overridden in the derived class.</p>
<p>My reply:</p>
<p>Yes &#8211; that&#8217;s the &#8220;typical&#8221; way, but even with inheritance, you can hit problems if you have written a descendant class for which the parent class suddenly is changed (which in essense if what you do with class helpers &#8211; modify the parent class, but without impacting code that aren&#8217;t using your extensions).</p>
<p>You wrote:</p>
<p>I would say “Try that with a class helper” but I wouldn’t want to waste your time, so instead simply read this:</p>
<p><a href="http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/" rel="nofollow">http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/</a></p>
<p>My reply:</p>
<p>I *have* read it, and have yet to need virtual methods in class helpers, since the way I use them mainly is to OO&#8217;ize old-style procedural-calls.</p>
<p>Like I said yesterday, I don&#8217;t expect to use Class Helpers to implement advanced routines, but for the simple extensions I am using them (like my TStream example yesterday), I find them extremely useful.</p>
<p>You wrote:</p>
<p>Can you “reintroduce” with a class helper?</p>
<p>Even if you can, you do not get the same behaviour that you would get with a regular class since you cannot qualify using a class helper name so there is no way to get at the hidden method as you can with an OO, but non-polymorphic, class &#8211; your derived helper would permanently and unavoidably deny access to any inherited method with the same signature (overloads will &#8211; I should say “might” &#8211; allow methods that differ in parameters alone to propogate into the derived helper).</p>
<p>My reply:</p>
<p>If I f.ex. introduce a method with identical sugnature in a class helper for TComboBox, I can call the original TComboBox method in one of two ways:</p>
<p>1) Introduce a wrapper call in my class helper (as illustrated in my example today). By marking it INLINE, I can even eliminate any code overhead.</p>
<p>2) If the call really originates in a parent to TComboBox, I can cast my variable to that parent (TCustomComboBox) in order to &#8220;escape&#8221; the class helper.</p>
<p>You wrote:</p>
<p>And worse &#8211; as your own example demonstrated quite nicely &#8211; you risk having code that could inadvertently change behaviour in response to a simple change the order of units in a uses list.</p>
<p>My reply:</p>
<p>What&#8217;s the difference in this and any other naming conflict you can encounter by having two libraries both defining a class TExtDialog, f.ex.? You could run into the exact same problem there, but I don&#8217;t see you objecting to normal class inheritance or ordinary OO programming <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>You wrote:</p>
<p>This makes perfect sense if you remember that they were designed for CODEGEAR to use “internally” so only had to suit the purposes to which CodeGear intended to put them, and that was to address a cross-platform issue between VCL and VCL.NET code.</p>
<p>My reply:</p>
<p>But then, why did CodeGear</p>
<p>1) Allow the syntax in Delphi Win32?</p>
<p>2) Allow Class Helper inheritance</p>
<p>3) Not make the compiler issue a warning, like it does with so many other things (deprecated, platform specific, hides earlier implementation, etc. etc.)?</p>
<p>You wrote:</p>
<p>if I understand correctly, they are used in D2007 primarily to avoid a breaking change between D2006 and D2007 &#8211; I doubt there will be any class helpers in the Delphi 2009 VCL source as this will be a breaking release so such temporary fixes are not needed.</p>
<p>My reply:</p>
<p>But then:</p>
<p>1) Why was Class Helpers (buggy) supported even in Delphi 2005?</p>
<p>2) Why was Class Helpers (fixed) supported even in Delphi 2006?</p>
<p>In other words &#8211; Class Helpers were NOT implemented in Delphi 2007 for Win32 to allow this non-breaking release. It&#8217;s the other way around &#8211; the non-breaking release TOOK ADVANTAGE of already existing Class Helper support in order to make the release non-breaking.</p>
<p>You wrote:</p>
<p>“But they are documented, so we are clearly supposed to use them” (paraphrase)</p>
<p>1) this ignores the fact that the same documentation being held up as validation their use contains a warning specifically suggesting that you do not.</p>
<p>Do we trust the documentation as an authority, or dismiss it as irrelevant? You seem to want to do both.</p>
<p>My reply:</p>
<p>I can&#8217;t remember I have ever seen that warning. I just tried it on my Delphi 2007, and there&#8217;s a warning there, but I can&#8217;t recall ever seeing that warning in neither Delphi 2005 nor Delphi 2006. So to my mind, the warning is an after-rationalization that they have come up with post-haste to try to put the cat back in the bag. Unfortunately, they are too late &#8211; the cat&#8217;s already out of the bag, all the way back from Delphi 2005 (where I started using them).</p>
<p>You wrote:</p>
<p>2) if the VCL source were not published there would have been no need to even mention class helpers, let alone document them. But since class helpers were inevitably going to be “on view” they had to be documented. Even without documentation someone would have found them in the VCL source, figured out how to use them and then excitedly told everyone the secret they had discovered.</p>
<p>My reply:</p>
<p>But why document them FULLY. Why not just &#8211; from the very onset (Delphi 2005) &#8211; state in the help file:</p>
<p>Class Helpers are an internal feature used by CodeGear to allow interface between .NET and VCL and is not to be used by other people.</p>
<p>and nothing more? And why &#8211; in the first place &#8211; port it to Win32, if it wasn&#8217;t that we were supposed to use them (and no &#8211; it wasn&#8217;t ported to Win32 to allow the non-breaking release of Delphi 2007, since they were there all the way back in Delphi 2005).</p>
<p>You wrote:</p>
<p>“They could yet implement them fully?”</p>
<p>Indeed they could, but why should they?</p>
<p>My reply:</p>
<p>Because it&#8217;s a NICE feature that allows me (and others) to implement small snippets of code into the VCL hieararchy without the need to re-compile it (and thus break compatibility with old code).</p>
<p>Yes &#8211; there are some problems and pitfalls with the specific implementation, but that could probably be solved in various ways &#8211; least of all are compiler warnings, where a class helper introduces methods that override or conflicts with existing names, and/or warnings where there&#8217;s a possibility for ambiguity in the use of a class helper (no need to warn about TStreamHelper.WriteInteger unless there&#8217;s a descendant or parent class that also has a WriteInteger with the same signature).</p>
<p>One could even allow these warnings to be promoted to errors on a project-by-project basis to force the programmers to resolve any ambiguity before allowing the program to compile.</p>
<p>You wrote:</p>
<p>CodeGear have &#8211; from the outset &#8211; told us that we should not be using them.</p>
<p>My reply:</p>
<p>Like I said, that&#8217;s a statement I don&#8217;t believe is true. I&#8217;ll try to see if I can find my old, dusty Delphi 2005 compiler and see if the warning is there in the help file all the way back then, but I don&#8217;t remember ever reading a warning about it in any help file until I today looked it up in Delphi 2007.</p>
<p>You wrote:</p>
<p>1) the documentation suggests, quite directly and really quite strongly, that class helpers are something that should not be used</p>
<p>My reply:</p>
<p>Yes &#8211; at least in Delphi 2007. Whether or not it was there in the Delphi 2005 documentation remains to be seen&#8230;</p>
<p>You wrote:</p>
<p>Yet despite all this, you believe that I am wrong to suggest that it would be sensible, at the very least, to heed that warning at #1, above.</p>
<p>My reply:</p>
<p>If by &#8220;heed that warning&#8221; you mean &#8220;don&#8217;t EVER use class helpers&#8221;, then, yes, I think you are wrong. Like any tool, class helpers can be mis-used, but if one is aware of the pitfalls, I don&#8217;t see anything wrong with using them.</p>
<p>If they are used (as I do) to make code more readable and maintainable, then I am all for it. Use the tools that you have available, but use them responsibly&#8230;</p>
<p>Should cars be illegal because they can kill people? <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  How about a power drill? <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jolyon Smith</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-167</link>
		<dc:creator>Jolyon Smith</dc:creator>
		<pubDate>Mon, 01 Sep 2008 12:43:23 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-167</guid>
		<description><![CDATA[@Keld

So let me see, depending on which class helper is &quot;visible&quot;, then this line of code:

  ComboBox.Add(&#039;&#039;);

could do two entirely different things?  And simply changing the order of your uses list could change that behaviour?

And you are offering this to support an argument in FAVOUR of class helpers?

Hmmmmmmm.

;)


As for the substance of your observations, I shall address the &quot;inheritance&quot; issue first then come back to the documentation issue.

Yes, name collisions occur with inheritance, but there are legitimate and reliable mechanisms for dealing with those.

Most typically if you have a method in a base class that has the same name in a derived class it is normally because that method is polymorphic - it will be virtual in the base class and overridden in the derived class.

I would say &quot;Try that with a class helper&quot; but I wouldn&#039;t want to waste your time, so instead simply read this:

http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/


Class helpers do not support &quot;proper OO&quot; as far as virtual methods are concerned.  Or perhaps more accurately, the Win32 compiler and RTL do not support it beyond allowing the syntax (*remember this, it will be crucial in my &quot;closing arguments&quot;.  lol).

Can you &quot;reintroduce&quot; with a class helper?

Even if you can, you do not get the same behaviour that you would get with a regular class since you cannot qualify using a class helper name so there is no way to get at the hidden method as you can with an OO, but non-polymorphic, class - your derived helper would permanently and unavoidably deny access to any inherited method with the same signature (overloads will - I should say &quot;might&quot; - allow methods that differ in parameters alone to propogate into the derived helper).

And worse - as your own example demonstrated quite nicely - you risk having code that could inadvertently change behaviour in response to a simple change the order of units in a uses list.

The compiler won&#039;t warn you if you derive Helper2 from Helper1 but then have Helper1 (accidentally or otherwise) HIDE Helper2.


Far from going to &quot;extended trouble to support helper inheritance&quot; it is clearly not (fully) supported at all.

As far as virtual method support is concerned, this - as I understand it - is a limitation of the Win32 implementation.  Virtual methods on class helpers ARE supported in Delphi.NET.

&quot;Ah see!  They just haven&#039;t got around to finishing the Win32 implementation yet.&quot; (speculated response)

You might think that - if it hadn&#039;t already been indicated that class helpers are working according &quot;As Designed&quot; in Win32.

This makes perfect sense if you remember that they were designed for CODEGEAR to use &quot;internally&quot; so only had to suit the purposes to which CodeGear intended to put them, and that was to address a cross-platform issue between VCL and VCL.NET code.  If there were different needs in the Win32 compiler vs the .NET compiler at that time, that would explain the differences in the implementation.

As clarified by other commenters, class helpers were introduced first in Delphi.NET (Delphi 8) - if I understand correctly, they are used in D2007 primarily to avoid a breaking change between D2006 and D2007 - I doubt there will be any class helpers in the Delphi 2009 VCL source as this will be a breaking release so such temporary fixes are not needed.

Again, if I understand correctly, the VCL.NET is a different matter of course - in that case class helpers are a permanent fixture required to address that VCL/VCL.NET issue (the details of which I don&#039;t have to hand but I&#039;m sure can be found quite easily if you are interested)


&quot;But they are documented, so we are clearly supposed to use them&quot; (paraphrase)

1) this ignores the fact that the same documentation being held up as validation their use contains a warning specifically suggesting that you do not.

Do we trust the documentation as an authority, or dismiss it as irrelevant?  You seem to want to do both.

2) if the VCL source were not published there would have been no need to even mention class helpers, let alone document them.  But since class helpers were inevitably going to be &quot;on view&quot; they had to be documented.  Even without documentation someone would have found them in the VCL source, figured out how to use them and then excitedly told everyone the secret they had discovered.

Who would have heeded any warnings then?

People would have felt that Borland/CodeGear were just trying to keep some candy treats for themselves.


&quot;They could yet implement them fully?&quot;

Indeed they could, but why should they?

CodeGear have - from the outset - told us that we should not be using them.

They might just as easily decide that they were a bad idea - or at least a poor implementation of a necessary idea - and choose to fundamentally change them or even remove them from the language completely and replace them with something else.

I&#039;m not saying they will (as I said before, I suspect they will remain in some form or another in connection to support a LINQ implementation), but if they did - or if they were changed in a way incompatible with current usage - no-one could reasonably complain that they weren&#039;t warned.


Let&#039;s review the facts:

1) the documentation suggests, quite directly and really quite strongly, that class helpers are something that should not be used

2) the apparent OO features and seeming OO syntax of class helpers clearly does not follow the OO implementation found in the rest of Delphi

3) even when used &quot;responsibly&quot; in an area of code, irresponsible use in another area (let us call it the &quot;problem area&quot;) can lead to side effects - namely compilation failures - outside of the problem area itself.  This is not typically a characteristic of a &quot;first class&quot; language feature.

Finally, and most damning of all:

4) the Win32 compiler supports a syntax that produces code for which runtime support is not provided (resulting in access violations)

5) the lack of runtime support is not considered a bug - it is &quot;As Designed&quot;


Yet despite all this, you believe that I am wrong to suggest that it would be sensible, at the very least, to heed that warning at #1, above.

The case for the prosecution rests.

:)


(But even after all that, I am not going to &quot;send the boys round&quot; if you wish to dance with this particular devil, by the pale moonlight or otherwise.

But I myself shall sit this one out and wait for the Gentlemen&#039;s Excuse Me)

:)]]></description>
		<content:encoded><![CDATA[<p>@Keld</p>
<p>So let me see, depending on which class helper is &#8220;visible&#8221;, then this line of code:</p>
<p>  ComboBox.Add(&#8221;);</p>
<p>could do two entirely different things?  And simply changing the order of your uses list could change that behaviour?</p>
<p>And you are offering this to support an argument in FAVOUR of class helpers?</p>
<p>Hmmmmmmm.</p>
<p> <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>As for the substance of your observations, I shall address the &#8220;inheritance&#8221; issue first then come back to the documentation issue.</p>
<p>Yes, name collisions occur with inheritance, but there are legitimate and reliable mechanisms for dealing with those.</p>
<p>Most typically if you have a method in a base class that has the same name in a derived class it is normally because that method is polymorphic &#8211; it will be virtual in the base class and overridden in the derived class.</p>
<p>I would say &#8220;Try that with a class helper&#8221; but I wouldn&#8217;t want to waste your time, so instead simply read this:</p>
<p><a href="http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/" rel="nofollow">http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/</a></p>
<p>Class helpers do not support &#8220;proper OO&#8221; as far as virtual methods are concerned.  Or perhaps more accurately, the Win32 compiler and RTL do not support it beyond allowing the syntax (*remember this, it will be crucial in my &#8220;closing arguments&#8221;.  lol).</p>
<p>Can you &#8220;reintroduce&#8221; with a class helper?</p>
<p>Even if you can, you do not get the same behaviour that you would get with a regular class since you cannot qualify using a class helper name so there is no way to get at the hidden method as you can with an OO, but non-polymorphic, class &#8211; your derived helper would permanently and unavoidably deny access to any inherited method with the same signature (overloads will &#8211; I should say &#8220;might&#8221; &#8211; allow methods that differ in parameters alone to propogate into the derived helper).</p>
<p>And worse &#8211; as your own example demonstrated quite nicely &#8211; you risk having code that could inadvertently change behaviour in response to a simple change the order of units in a uses list.</p>
<p>The compiler won&#8217;t warn you if you derive Helper2 from Helper1 but then have Helper1 (accidentally or otherwise) HIDE Helper2.</p>
<p>Far from going to &#8220;extended trouble to support helper inheritance&#8221; it is clearly not (fully) supported at all.</p>
<p>As far as virtual method support is concerned, this &#8211; as I understand it &#8211; is a limitation of the Win32 implementation.  Virtual methods on class helpers ARE supported in Delphi.NET.</p>
<p>&#8220;Ah see!  They just haven&#8217;t got around to finishing the Win32 implementation yet.&#8221; (speculated response)</p>
<p>You might think that &#8211; if it hadn&#8217;t already been indicated that class helpers are working according &#8220;As Designed&#8221; in Win32.</p>
<p>This makes perfect sense if you remember that they were designed for CODEGEAR to use &#8220;internally&#8221; so only had to suit the purposes to which CodeGear intended to put them, and that was to address a cross-platform issue between VCL and VCL.NET code.  If there were different needs in the Win32 compiler vs the .NET compiler at that time, that would explain the differences in the implementation.</p>
<p>As clarified by other commenters, class helpers were introduced first in Delphi.NET (Delphi 8) &#8211; if I understand correctly, they are used in D2007 primarily to avoid a breaking change between D2006 and D2007 &#8211; I doubt there will be any class helpers in the Delphi 2009 VCL source as this will be a breaking release so such temporary fixes are not needed.</p>
<p>Again, if I understand correctly, the VCL.NET is a different matter of course &#8211; in that case class helpers are a permanent fixture required to address that VCL/VCL.NET issue (the details of which I don&#8217;t have to hand but I&#8217;m sure can be found quite easily if you are interested)</p>
<p>&#8220;But they are documented, so we are clearly supposed to use them&#8221; (paraphrase)</p>
<p>1) this ignores the fact that the same documentation being held up as validation their use contains a warning specifically suggesting that you do not.</p>
<p>Do we trust the documentation as an authority, or dismiss it as irrelevant?  You seem to want to do both.</p>
<p>2) if the VCL source were not published there would have been no need to even mention class helpers, let alone document them.  But since class helpers were inevitably going to be &#8220;on view&#8221; they had to be documented.  Even without documentation someone would have found them in the VCL source, figured out how to use them and then excitedly told everyone the secret they had discovered.</p>
<p>Who would have heeded any warnings then?</p>
<p>People would have felt that Borland/CodeGear were just trying to keep some candy treats for themselves.</p>
<p>&#8220;They could yet implement them fully?&#8221;</p>
<p>Indeed they could, but why should they?</p>
<p>CodeGear have &#8211; from the outset &#8211; told us that we should not be using them.</p>
<p>They might just as easily decide that they were a bad idea &#8211; or at least a poor implementation of a necessary idea &#8211; and choose to fundamentally change them or even remove them from the language completely and replace them with something else.</p>
<p>I&#8217;m not saying they will (as I said before, I suspect they will remain in some form or another in connection to support a LINQ implementation), but if they did &#8211; or if they were changed in a way incompatible with current usage &#8211; no-one could reasonably complain that they weren&#8217;t warned.</p>
<p>Let&#8217;s review the facts:</p>
<p>1) the documentation suggests, quite directly and really quite strongly, that class helpers are something that should not be used</p>
<p>2) the apparent OO features and seeming OO syntax of class helpers clearly does not follow the OO implementation found in the rest of Delphi</p>
<p>3) even when used &#8220;responsibly&#8221; in an area of code, irresponsible use in another area (let us call it the &#8220;problem area&#8221;) can lead to side effects &#8211; namely compilation failures &#8211; outside of the problem area itself.  This is not typically a characteristic of a &#8220;first class&#8221; language feature.</p>
<p>Finally, and most damning of all:</p>
<p>4) the Win32 compiler supports a syntax that produces code for which runtime support is not provided (resulting in access violations)</p>
<p>5) the lack of runtime support is not considered a bug &#8211; it is &#8220;As Designed&#8221;</p>
<p>Yet despite all this, you believe that I am wrong to suggest that it would be sensible, at the very least, to heed that warning at #1, above.</p>
<p>The case for the prosecution rests.</p>
<p> <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>(But even after all that, I am not going to &#8220;send the boys round&#8221; if you wish to dance with this particular devil, by the pale moonlight or otherwise.</p>
<p>But I myself shall sit this one out and wait for the Gentlemen&#8217;s Excuse Me)</p>
<p> <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Keld R. Hansen</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-166</link>
		<dc:creator>Keld R. Hansen</dc:creator>
		<pubDate>Mon, 01 Sep 2008 11:18:07 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-166</guid>
		<description><![CDATA[For me, the mere facts that

1) There is no compiler warning emitted when the compiler encounters a CLASS HELPER definition

2) The ability to inherit from a previous CLASS HELPER exists

show me that

1) Borland/CodeGear didn&#039;t really mean the warning at the time of implementation - at least not at the time of designing the feature

2) The implementors have at least thought &quot;outside the box&quot; in that two class helpers for a given class CAN be active AT THE SAME TIME. Therefore it was not solely intended for the use you describe - otherwise why go to the extended trouble of implementing CLASS HELPER inheritance?

Also, class helpers doesn&#039;t create problems that doesn&#039;t already exists with inheritance. You can have name conflicts and signature conflicts in a classical OO hiearachy just as you can in a CLASS HELPER hiearachy.

CLASS HELPERs can also call parent CLASS HELPERs using the INHERITED syntax, such as in this nonsense-example:

--------------------------------------------------------------------------------

UNIT Helper1;

TYPE
  TClassHelper1 = CLASS HELPER FOR TComboBox
                    FUNCTION    Add(CONST STR : STRING ; OBJ : TObject = NIL) : INTEGER;
                  END;

{ TClassHelper1 }

FUNCTION TClassHelper1.Add(CONST STR : STRING ; OBJ : TObject) : INTEGER;
  BEGIN
    Result:=Items.AddObject(STR,OBJ)
  END;

--------------------------------------------------------------------------------

UNIT Helper2;

TYPE
  TClassHelper2 = CLASS HELPER(TClassHelper1) FOR TComboBox
                    FUNCTION    Add(CONST STR : STRING ; OBJ : TObject = NIL) : INTEGER;
                    FUNCTION    UncheckedAdd(CONST STR : STRING ; OBJ : TObject = NIL) : INTEGER;
                  END;

{ TClassHelper2 }

FUNCTION TClassHelper2.Add(CONST STR : STRING ; OBJ : TObject) : INTEGER;
  BEGIN
    IF STR=&#039;&#039; THEN Result:=-1 ELSE Result:=UncheckedAdd(STR,OBJ)
  END;

FUNCTION TClassHelper2.UncheckedAdd(CONST STR : STRING ; OBJ : TObject) : INTEGER;
  BEGIN
    Result:=INHERITED Add(STR,OBJ)
  END;

--------------------------------------------------------------------------------

UNIT Main;

USES Helper1,Helper2;

procedure TForm2.FormCreate(Sender: TObject);
begin
  ComboBox1.Add(&#039;&#039;);
  ComboBox1.Add(&#039;1234&#039;)
end;

--------------------------------------------------------------------------------

which also demonstrates the ability to &quot;Rename&quot; a parent&#039;s class helper method in descendant class helpers so as to provide access to both from programs that use both ClassHelper1 and ClassHelper2.]]></description>
		<content:encoded><![CDATA[<p>For me, the mere facts that</p>
<p>1) There is no compiler warning emitted when the compiler encounters a CLASS HELPER definition</p>
<p>2) The ability to inherit from a previous CLASS HELPER exists</p>
<p>show me that</p>
<p>1) Borland/CodeGear didn&#8217;t really mean the warning at the time of implementation &#8211; at least not at the time of designing the feature</p>
<p>2) The implementors have at least thought &#8220;outside the box&#8221; in that two class helpers for a given class CAN be active AT THE SAME TIME. Therefore it was not solely intended for the use you describe &#8211; otherwise why go to the extended trouble of implementing CLASS HELPER inheritance?</p>
<p>Also, class helpers doesn&#8217;t create problems that doesn&#8217;t already exists with inheritance. You can have name conflicts and signature conflicts in a classical OO hiearachy just as you can in a CLASS HELPER hiearachy.</p>
<p>CLASS HELPERs can also call parent CLASS HELPERs using the INHERITED syntax, such as in this nonsense-example:</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>UNIT Helper1;</p>
<p>TYPE<br />
  TClassHelper1 = CLASS HELPER FOR TComboBox<br />
                    FUNCTION    Add(CONST STR : STRING ; OBJ : TObject = NIL) : INTEGER;<br />
                  END;</p>
<p>{ TClassHelper1 }</p>
<p>FUNCTION TClassHelper1.Add(CONST STR : STRING ; OBJ : TObject) : INTEGER;<br />
  BEGIN<br />
    Result:=Items.AddObject(STR,OBJ)<br />
  END;</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>UNIT Helper2;</p>
<p>TYPE<br />
  TClassHelper2 = CLASS HELPER(TClassHelper1) FOR TComboBox<br />
                    FUNCTION    Add(CONST STR : STRING ; OBJ : TObject = NIL) : INTEGER;<br />
                    FUNCTION    UncheckedAdd(CONST STR : STRING ; OBJ : TObject = NIL) : INTEGER;<br />
                  END;</p>
<p>{ TClassHelper2 }</p>
<p>FUNCTION TClassHelper2.Add(CONST STR : STRING ; OBJ : TObject) : INTEGER;<br />
  BEGIN<br />
    IF STR=&#8221; THEN Result:=-1 ELSE Result:=UncheckedAdd(STR,OBJ)<br />
  END;</p>
<p>FUNCTION TClassHelper2.UncheckedAdd(CONST STR : STRING ; OBJ : TObject) : INTEGER;<br />
  BEGIN<br />
    Result:=INHERITED Add(STR,OBJ)<br />
  END;</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>UNIT Main;</p>
<p>USES Helper1,Helper2;</p>
<p>procedure TForm2.FormCreate(Sender: TObject);<br />
begin<br />
  ComboBox1.Add(&#8221;);<br />
  ComboBox1.Add(&#8217;1234&#8242;)<br />
end;</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>which also demonstrates the ability to &#8220;Rename&#8221; a parent&#8217;s class helper method in descendant class helpers so as to provide access to both from programs that use both ClassHelper1 and ClassHelper2.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jolyon Smith</title>
		<link>http://www.deltics.co.nz/blog/?p=282&#038;cpage=1#comment-164</link>
		<dc:creator>Jolyon Smith</dc:creator>
		<pubDate>Mon, 01 Sep 2008 06:58:42 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=282#comment-164</guid>
		<description><![CDATA[Hi Lars - I think the problem (and I&#039;m only speculating) is that they were designed to solve a very specific problem, not as a general purpose language feature, and that specific problem required them to be used without having to identify them as such (or at least that was desirable).

i.e. to be able to use the &quot;helped&quot; class as if it actually contained the helper additions.

For that design goal to be realised, there has to be only one helper &quot;allowed&quot;, otherwise you have all sorts of problems if two helpers introduce methods with the same signature.

Or you have to devise a complicated mechanism to allow such collisions to be resolved, but if you never intended them to be used in situations where collisions could arise, why bother?

Similarly the presumably helpers in the Win32 VCL didn&#039;t require virtual method and override support, so whilst that is implemented and supported in the .NET compiler, the Win32 compiler supports the *syntax* but the RTL implementation isn&#039;t actually complete - as of Delphi 2007 at least.

http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/

Note CodeGear&#039;s response to being told of this &quot;unfinished&quot; implementation.....  &quot;As Designed&quot;.

I read this as indicating that - as more or less already stated - class helpers were implemented to meet a specific, internal need.  They were documented to explain their purpose, but they were never designed nor intended for general purpose use.

Some people choose not to see it that way, I guess.  :)

Whether the design and/or implementation will ever be finished/revised to a point where they may be respectably considered a &quot;first class&quot; language feature for general use is still open to question I suppose.]]></description>
		<content:encoded><![CDATA[<p>Hi Lars &#8211; I think the problem (and I&#8217;m only speculating) is that they were designed to solve a very specific problem, not as a general purpose language feature, and that specific problem required them to be used without having to identify them as such (or at least that was desirable).</p>
<p>i.e. to be able to use the &#8220;helped&#8221; class as if it actually contained the helper additions.</p>
<p>For that design goal to be realised, there has to be only one helper &#8220;allowed&#8221;, otherwise you have all sorts of problems if two helpers introduce methods with the same signature.</p>
<p>Or you have to devise a complicated mechanism to allow such collisions to be resolved, but if you never intended them to be used in situations where collisions could arise, why bother?</p>
<p>Similarly the presumably helpers in the Win32 VCL didn&#8217;t require virtual method and override support, so whilst that is implemented and supported in the .NET compiler, the Win32 compiler supports the *syntax* but the RTL implementation isn&#8217;t actually complete &#8211; as of Delphi 2007 at least.</p>
<p><a href="http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/" rel="nofollow">http://blog.excastle.com/2007/08/29/unfinished-delphi-feature-of-the-day-virtual-class-helper-methods/</a></p>
<p>Note CodeGear&#8217;s response to being told of this &#8220;unfinished&#8221; implementation&#8230;..  &#8220;As Designed&#8221;.</p>
<p>I read this as indicating that &#8211; as more or less already stated &#8211; class helpers were implemented to meet a specific, internal need.  They were documented to explain their purpose, but they were never designed nor intended for general purpose use.</p>
<p>Some people choose not to see it that way, I guess.  <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Whether the design and/or implementation will ever be finished/revised to a point where they may be respectably considered a &#8220;first class&#8221; language feature for general use is still open to question I suppose.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
