[fpc-pascal] Re: FPC class syntax was extended to support delphi code

Arioch1 the_Arioch at nm.ru
Sat Feb 2 09:38:08 CET 2013


To draw a perspective, i am coming from, i want to use a library, that is
built with long procedures, having 5-10 parametes, of those i usually really
only need to set one or two.

 So i naturally decided to make a wrapper with fluent-style, chained API, so
i can only set those params that i actually need customized. But Fluent API
requires automatic lifetime management, which in Delphi means using
ref-counted interfaces.

 And that comes with a problem - constructor return an object, not an
interface.
 And even i make all the methods on object go protected and on;y exposed via
interface, i have doubts that all the compilers would successfully
implicitly typecast it. Most probably they would not. And doing manual
typecast damages clean and simple ease of use for Fluent-style API.

 Maybe you know about Jedi CodeLib library. It supports FPC 2.4 and recently
unofficial patchset for 2.6 was released.
 It has a TJclStringList/IJclStringList extenstion of a stock class.

 Recently on stackoverflow there came yet another question that in effect
was reduced "how to read all the lines from text file and split them on some
delimeter.

 My usual answer for this goes along the lines
var s: string; isl1, isl2: IJclStringList;
...
isl1 := TJclStringList.Create; isl1.LoadFromFile(...);
...
for s in isl1 do begin
   isl2.Split(s, delimeter-char).Trim.Add(['some string', 'some another
string']).UpperCase. ...; 
   // refining of strings can be chained

    // iterating through refined split data in isl2
end;

 This time i was in a haste and drafted like
isl1 := TJclStringList.Create.LoadFromFile(...);

 Well, actually that most probably would not even compile, but if it would -
it would be a memory leak, because between constructor and LoadFrom*** call
- there is no interface reference yet, but a PODO reference.

 This obvious error, but is so easy to make when u want to type fast and
fluentized.
 So that gave me another reason to try to side-step Delphi object
constructor.
 But then how would i call factory-method? some simple name like "a", "b",
"c,", "_" - would have no sense an d look ugly and hard to remember. Some
lone name would harm conciseness of fluent style and would be against OOP
"object.verb" style. It would be like making method
TStringList.LoadStringListFromFile - DRY principle is good even in naming 

 Then i got a flash and devised to outsmart Delphi with a construct like
this:
type
  TData = class end;  // some object we need to operate upon
  IDataHandler = interface end; //some methods to make Fluent-Style,
daisy-chain API

  { TDataExporter }

  TDataExporter = class(IDataHandler, TInterfacedObject)
     protected
        Payload: TData;
        constructor CreateFor(const d: TData);
        class function    MakeNewExporter(const d: TData): IDataHandler;
static;

        /// all other functions, setting this or that parameter and
        /// returning Self as IDataHandler

     public
        procedure AfterConstruction; override;

        class property Factory[Payload: TData]: IDataHandler read
MakeNewExporter; default;
  end;                          


{ TDataExporter }

class function TDataExporter.MakeNewExporter(const d: TData): IDataExporter;
begin
  Result := TDataExporter.CreateFor(d);
end;

procedure TDataExporter.AfterConstruction;
begin
  if Self.Payload = nil then raise Exception.Create('You should not create
via inherited TObject.Create!');
end;

constructor TDataExporter.CreateFor(const d: TData);
begin
  if d = nil then raise Exception.Create('Payload data is required!');
  Self.Payload := d;
end;                    

 And you know what... dunno if it works or not, but at least it compiled in
CT 3.10 Win64


var i: IDataHandler;
begin
  i := TDataExporter[TData.Create];
end;

procedure TForm1.FormCreate(Sender: TObject);
var i: IDataHandler;  d: TData;
begin
  d := TData.Create;
  i := TDataExporter[d];
end;    

unit1.pas(52,22) Error: Illegal qualifier

 in both Delphi and ObjFpc mode  :-(((





Arioch1 wrote
> Can FPC have default class properties in Delphi mode or even ObjFpc mode?
> Andreas Schneider-7 wrote
>> I think they come in very handy for the Singleton OOP concept. You need
>> to 
>> have a "factory" that handles the object query/instantiation. If no
>> instance 
>> is available, it creates a new one (and stores it) and if one is already 
>> available, it just returns that.
>> Naturally that looks better to have TSomeClass.GetInstance() instead of 
>> GetInstanceOfSomeClass() ...
>> Sure, it's possible to do without class methods, but from an OOP
>> viewpoint it 
>> just looks and feels wrong ;-) (imho)





--
View this message in context: http://free-pascal-general.1045716.n5.nabble.com/FPC-class-syntax-was-extended-to-support-delphi-code-tp2819586p5712716.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.



More information about the fpc-pascal mailing list