Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2020-02

reference/pointer to class function/constructor ?

3 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Harald Houppermans

*** 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.

Reply by email

Nikolai Zhubr
to Harald Houppermans

Hi,
20.02.2020 10:21, Harald Houppermans via fpc-devel: [...]

Show quoted text 9 lines
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.

I'd guess your initializer function in fact does not need to be a class member. Actually, a class function is a rather "weak" memeber already. So then you just declare a regular function type and some few regular functions as initializers. Now, from within such regular function, you may call some class functions if you need so. Not very elegant but supposedly should work.

HTH

Regards,
Nikolai

Show quoted text 122 lines
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. _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Sven Barth
to Harald Houppermans: *** Longer version/more explanation ***: Hello Free Pascal Compiler Developers !…

Harald Houppermans via fpc-devel schrieb
am Fr., 21. Feb. 2020, 12:37:

Show quoted text 80 lines
*** 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.

If you don't need the initializers to be virtual or have access to the class type using Self you can declare them as static (class procedure Initialize; static;), then you can assign them to normal procedure variables (TInitializer = procedure;).

Regards,
Sven

Reply by email