[fpc-devel] reference/pointer to class function/constructor ?
Harald Houppermans
hbthouppermans at home.nl
Thu Feb 20 08:21:41 CET 2020
*** Longer version/more explanation ***:
Hello Free Pascal Compiler Developers !
Simplified story:
I currently have a need/desire to do the following:
I have a library which has different unit versions like so:
version1.pas
version2.pas
version3.pas
Some projects only need 1 and 2.
Some maybe 1 2 and 3.
Adding files to project (in Delphi) is handy it tells me exactly where stuff
is and avoids search path confusion and using old versions in environment
and prevents single point of failure
in case IDE is deleted/uninstalled or updated then projects also continue
working.
Also versions could be under development and sometimes a particular version
must not be included, also new versions can be created like version4.pas.
There is a GUI control/component which can be configured to support up to a
certain ammount of versions. Version 3 currently uses 2 uses 1 and so forth,
in principle is flexible via inheritance
even if inheritance chain is slightly broken can be temporarely fixed and so
forth, this is not 100% required but gives options.
The classes inside the versions are currently use a class function as an
initializer which looks as follows:
Tversion3 = class(Tversion2)
class function Initialize;
end;
The idea is to let the user set the desired version for the GUI
control/component for example;
TGUIControl = class
Version : TVersion;
end;
Now the idea is to seperate TVersion into a seperate unit as follows:
Versions.pas:
TVersion = ( v1, v2, v3 );
The idea is now further to implement a plugin table so that unit versions
that are included can automatically be plugged into this plugin table for
example:
VersionSupported[TVersion] of boolean;
^ So far this is just a concept to show with booleans this would be easy to
do.
Now version1.pas can simply write an initializer as follows;
uses
versions.pas
initializer
Version[v1] := True;
end.
However what if an initialize class function must be called, also what if
these must happen in a certain order.
For example v1 must be initialized first, then v2, then v3, because of
inheritance and also some base classes and library classes in another unit
which is what version 1 inherits from.
Anyway since these initializers already exist, in principle only the highest
version needs to be called and it will call the lower ones via the
inheritance tree "inherited create".
But what if this highest version is not there ? Then the next lowering
version should be called.
So now that I write this I realize what needs to be done.
Some an initializer variable needs to be set. (An array of initiliazer was
my first idea, it would also be nicer this way then the code can traverse
this array and see which versions initialized).
So I will stay with my initialize thought lol:
VersionInitialize : array[Tversion] of Tinitializer;
Now I need a type to the initialize function which is a class function, I
simply tried:
type
Tinitializer = class function; // this don't work in Delphi
I also tried:
Tinitializer = ^class function; // this don't work in Delphi.
Since writing TsomeObject.Initializer is weird might initialize thought was
to use a constructor which is a little bit more strange/inefficient maybe
but keeps code consistent in case class functions or turned into method
functions.
Tinitializer = constructor;
Tinitializer = ^constructor;
Tinitializer = class constructor;
Tinitializer = ^class constructor;
None of this seems possible ?!?
So it seems that my fair that I require some language feature that is not
available might be true.
If so try and understand it and try and create a plugin system for units, to
automatically initialize via arrays and plugin tables and constructors and
such in an object orientated way where inheritance and order also plays a
roll to some degree. If you can prove to me that this can be done with new
language features that would be great !
Otherwise "Houston we have a problem" and we need more powerfull language
extensions/features.
In case you agree with this then my hope is that if Free Pascal implements
it maybe Delphi will some day too ! ;) =D
Bye for now,
Skybuck =D
*** Shorter version / less explanation ***:
(Alternative shorter version):
I want/have the need to do the following, I want one unit as follows:
UnitVersion:
type
TVersion =
(
v1,
v2,
v3
)
I want to create some kind of pluggeable/plugin array to c;ass functions
like so:
(class functions can be called without creating an object like so
TSomeObject.ClassFunction;)
TInitializer = class function;
// could also be a constructor maybe
TInitialize = class constructor;
TInitializerArray = array[TVersion] of TIntializer;
var
InitializerArray : TInitializerArray;
Then the user can add certain units to the project yes or no... certain
versions.
For example version v1 and v2, but not v3.
Version1 and Version2 should "plug themselfes into this array" like so:
unit version 1
type
Tversion1 = class
class function Initialize;
end;
initialization
UnitVersion.InitializerArray[v1] := TVersion1.Initializer;
unit version 2
type
Tversion2 = class
class function Initialize;
end;
initialization
UnitVersion.InitializerArray[v2] := TVersion2.Initializer;
The idea is then that user code can use
UnitVersion.pas and include only version 1 and version 2.
And other code can then automate the initialization without breaking code.
If version 3 were added it would break code, cause version3.pas might not be
present or included in project.
So automation code should work even if a certain unit is not present.
Currently initialization is done with class functions.
Not sure if it's possible to make pointers to class functions.
With method pointers this would be easy/doable.
But now I am not sure if this is possible.
It's getting late... tomorrow I will do more re-search into this.
But perhaps somebody already knows how to solve this.
Bye for now,
Skybuck.
More information about the fpc-devel
mailing list