Recent

Author Topic: Type helpers and properties  (Read 260 times)

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
Type helpers and properties
« on: October 03, 2024, 07:14:08 pm »
According to the docs https://wiki.freepascal.org/Helper_types

Restrictions

A helper type may not

    contain (class) destructors (except in trunk FPC 3.3.1)

    contain class constructors (except in trunk FPC 3.3.1)

    contain fields

    contain abstract methods

    "override" virtual methods of the extended class (they can be hidden by the helper though)

When it comes to the matter of fields although they can't have fields in their type definitions, is it possible for them to reference other values they initialize themselves, eg allocate some memory or some records and store the values there, or reference some values initialized elsewhere?

Consider this example I run queries on some database connections whose settings are stored in a database table where they have GUIDs.

So if two or more queries connect to the same connection it will be better to check if a database with that GUID is already open, and use that connection rather create a new, some kind of poor man's connection pool.

So a type helper with a TConnection.GUID setter and getter would read and write that GUID, along the lines of TConnection.SetGUID(GUID) which could be stored in some other list, probably a global or static structure owned by the application.

Does this make sense?

Lazarus 3.0/FPC 3.2.2

Warfley

  • Hero Member
  • *****
  • Posts: 1749
Re: Type helpers and properties
« Reply #1 on: October 04, 2024, 12:27:59 am »
A type helper can simply not change the memory layout of the type. Basically it's just syntactic sugar that turns functions into (non virtual) methods. Meaning at it's core, what it's doing is just a bit of syntactic sugar turning this:
Code: Pascal  [Select][+][-]
  1. procedure TMyHelper.Foo;
  2. begin
  3.   WriteLn(Self.Field);
  4. end;
  5.  
  6. // Usage
  7. myVar.Foo;
Into:
Code: Pascal  [Select][+][-]
  1. procedure $TMyType_foo(var aInstance: TMyType);
  2. begin
  3.   WriteLn(aInstance.Field);
  4. end;
  5.  
  6. //and myVar.Foo becomes
  7. $TMyType_foo(myVar)

But as long as you don't need to change the memory of the type, you can just use getter and setter to existing fields to your liking:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. {$ModeSwitch typehelpers}
  3.  
  4. type
  5.   TMyRec = record
  6.     A: Integer;
  7.   end;
  8.  
  9.   TMyHelper = type helper for TMyRec
  10.   private
  11.     function GetB: Integer;
  12.     procedure SetB(AValue: Integer);
  13.   public
  14.   property B: Integer Read GetB write SetB;
  15.   end;
  16.  
  17. function TMyHelper.GetB: Integer;
  18. begin
  19.  Result := A * 2;
  20. end;
  21.  
  22. procedure TMyHelper.SetB(AValue: Integer);
  23. begin
  24.   A := AValue div 2;
  25. end;
  26.  
  27. var
  28.   r: TMyRec;
  29. begin
  30.   r.A:=1;
  31.   WriteLn(r.B);
  32.   r.B:=4;
  33.   WriteLn(r.A);
  34. end.

 

TinyPortal © 2005-2018