[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