[fpc-devel] RFC: Delphi style class helpers
Jonas Maebe
jonas.maebe at elis.ugent.be
Tue Dec 21 11:04:06 CET 2010
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
More information about the fpc-devel
mailing list