10

All of the documentation versions, including the one most up to date gives the following class/record helper syntax:

type
   identifierName = class|record helper [(ancestor list)] for TypeIdentifierName
     memberList
   end;

And it only explains what...

The ancestor list is optional. It can be specified only for class helper.

... and goes into dire details no further. An usage examples in the rest of the documentation topic merely exploit the fact what ancestor list is optional. All of EMBA's code I've seen as well as all of third-party code does not use this ancestor list part.

So, my questions are outlined in the title:

  • What the purpose of ancestor list in the class helper syntax?
  • Where it is documented?
  • Are there any usage example(s)?
Free Consulting
  • 4,300
  • 1
  • 29
  • 50

1 Answers1

12

It allows for inheritance of helpers:

{$APPTYPE CONSOLE}

type
  TObjectHelper = class helper for TObject
    procedure Foo;
  end;

  TObjectHelperAgain = class helper(TObjectHelper) for TObject
    procedure Bar;
  end;

procedure TObjectHelper.Foo;
begin
  Writeln('Foo');
end;

procedure TObjectHelperAgain.Bar;
begin
  Writeln('Bar');
end;

begin
  with TObject.Create do
  begin
    Foo;
    Bar;
  end;
end.

This is one way to work around the limitation that there can be only a single helper active at any particular code location.

So far as I can tell, there is no documentation for the ancestor list.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • FWIW, the derived object helper can be a helper for a ***derived*** class as well. IOW, this also works (compiles and produces expected result): `TObjectHelperAgain = class helper(TObjectHelper) for TList`. Just tried it. Of course I would call it `TListHelper`, then. – Rudy Velthuis Sep 20 '14 at 17:02
  • @rudy presumably the compiler would check that the helpees are related by inheritance in the obvious way. – David Heffernan Sep 20 '14 at 17:09
  • 2
    But `TStreamHelper = class helper(TListHelper) for TStream` won't compile. So it must be the same or a derived class that is being helped, and `TSTream` does not derive from `TList`. – Rudy Velthuis Sep 20 '14 at 17:09
  • Ok, I wrote the above comment before I saw yours. `` – Rudy Velthuis Sep 20 '14 at 17:10
  • The help text implies the ancestor list is valid for record helpers as well, but it is not. – LU RD Sep 20 '14 at 18:46
  • @LU the docs do also say *The ancestor list is optional. It can be specified only for class helper.* – David Heffernan Sep 20 '14 at 18:48
  • 2
    Thanks! I'm accepting your answer as solution, but for sake of completeness could you please add some input on **list** thing, which implies multiple identifiers as ancestors. If any, ofc. – Free Consulting Sep 21 '14 at 21:24
  • It's always just a single ancestor I think. I don't think you can add support for interfaces! – David Heffernan Sep 22 '14 at 05:59
  • 2
    Yes, if you attempt to add more than one item in the list you get *[dcc32 Error]: E2029 ')' expected but ',' found* – David Heffernan Sep 22 '14 at 08:02