On 21 Dec 2010, at 10:13, Sven Barth wrote:

Am 21.12.2010 00:16, schrieb Jonas Maebe:

Note that Delphi-style class helpers have several limitations that still have to be added to your patch: a) from http://docwiki.embarcadero.com/RADStudio/2010/en/Class_and_Record_Helpers : "You can define and associate multiple helpers with a single type. However, only zero or one helper applies in any specific location in source code. The helper defined in the nearest scope will apply. Class or record helper scope is determined in the normal Delphi fashion (for example, right to left in the unit's uses clause)." -- In Objective-C, there is no limit on the number of categories for a class that applies at the same time.

I don't know whether we should really follow this limitation (and when, then only in mode Delphi)

I would suggest asking on the Embarcadero forums what the reason is for this limitation. It would be annoying to have to add to wiki/ User_Changes_2.6.2 "Disabled multiple class helpers for a single class because it breaks/conflicts with/... X", like we have had to do already with several other cases where we removed what we considered to be useless limitations of Delphi features. The fact that it works in Objective-C/Pascal does not mean that it also fits to Object Pascal, because both languages are quite different (and because Objective-C/Pascal has a complex runtime system that does a lot of things behind your back).

Regarding some of the other limitations mentioned earlier: it seems that in Delphi 2010, you can add virtual methods to a class helper: http://windwings.wordpress.com/2009/10/07/turbocharging-delphi-2010-adding-dynamic-functionality-to-3rd-party-frameworks-read-vcl/ . You cannot override any methods of a helped class, but you can override virtual methods defined in one class helper in a class helper that inherits from it. Apparently support for class constructors/ destructors has also been added to class helpers.

This feature (virtual class helper methods) might be part of the reason why only one class helper can be used, depending on how they handle the class helper VMTs. You start getting some kind of multiple inheritance with multiple VMTs in terms of figuring out which class helper VMT to pass when calling one class helper method from another class helper.

Take this example:

*** unit1:

type
  tclasshelperbase = class helper for tobject
    procedure test; virtual;
  end;

  ttestcaller = class helper for tobject
    procedure calltest;
  end;


procedure tclasshelperbase.test;
  begin
    writeln('in base');
  end;

procedure ttestcaller.calltest;
  begin
    test;
  end;

*** unit 2:

type
  tclasshelperderived = class helper(tclasshelperbase) for tobject
    procedure test; override;
  end;

procedure tclasshelperderived.test;
  begin
    writeln('in derived');
  end;

*** main program:
uses
  unit1, unit2;
var
  o: tobject;
begin
  o:=tobject.create;
  o.calltest;
end.

Now which "test" should be called from ttestcaller.calltest? Since both unit1 and unit2 are in scope, I'd assume tclasshelperderived.test. But how does ttestcaller.calltest get the VMT of tclasshelperderived? Do you pass a linked list or array of VMTs of all class helper hierarchies currently in scope to all class helper routines, which then walk this list/array every time in search for the appropriate VMT to use?


Jonas
_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to