Lazarus, helper properties of freepascal lazarus / 64-FPC development ---------------------------------------------------------------------- staratel20 · 2016-03-26 07:53 Good day. Often needed some List with additional properties. Easiest example - TListBox with boolean property Checked, and for example we need also boolean property Founded. So, very abstract(and only for example), can looks like: QuoteTCheckedList=class   property Item[AIndex:integer]:TStringList read GetItem;default;   property Checked[AIndex:integer]:TBoolList read GetChecked;   property Founded[AIndex:integer]:TBoolList read GetState; end; MyStr :TCheckedList; after that we access to properties: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  MyStr.Checked[i];   MyStr.Founded[i];   // .. and so on. looks poor   What I propose. Syntax, something like: QuoteTCheckedList=class   property Item[AIndex:integer]:TStringList read GetItem;default;   property Checked[AIndex:integer]:TBoolList read GetChecked;attached;  // attached to default property   property Founded[AIndex:integer]:TBoolList read GetState;attached;  // attached to default property end; and after that we can write the same like: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i MyStr[i].Checked;   // will call GetChecked[i]MyStr[i].Founded;   // will call GetFounded[i]  .. and so on. looks good  Interest what you think about it. ---------------------------------------------------------------------- Thaddy · 2016-03-26 08:05 You can use a type helper for the Item type to achieve just that!. I'll see if I can come up with a small example later. ---------------------------------------------------------------------- staratel20 · 2016-03-26 08:18 I would thanks a lot) ---------------------------------------------------------------------- staratel20 · 2016-03-27 12:31 I read carefully this article(and continue discover it): http://wiki.freepascal.org/Helper_types but not sure that is possible realize what I'm talking about without changing to FPC core. At first if I'm extend TStringList with class TCheckedStringList - property Items are already busy. But I don't need changing behaviour of Items-property. So more deployed I need next behaviour: Quotes:string; s:=MyStr;  // will call Items of class TStringList MyStr.Checked;   // will call GetChecked of TCheckedStringList MyStr.Founded;   // will call GetFounded of TCheckedStringList Also I think that my suggested syntax is more simple and intuitive. Can I hope that something kind of this will be realized in next FPC versions? ---------------------------------------------------------------------- skalogryz · 2016-03-27 20:04 why TCheckedList returns lists ? (TStringList, TBoolList?) Is it some sort of 2d-array... a list of lists? But if you need to add these properties to TListBox, this is what you could do using helpers Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TListBoxChecked = class helper for TListBox  protected    function GetChecked(i: integer): Boolean;  public    property Checked[i: integer]: Boolean read GetChecked;  end;...function TListBoxChecked.GetChecked(i: integer): Boolean;begin  if not Assigned(Objects[i]) then Result:=false  else Result:=TMyObject(Objects[i]).checked;end; The actual implementation of .GetChecked() (or SetChecked()) depends on how you store "checked" value for an item within TListBox. ---------------------------------------------------------------------- staratel20 · 2016-03-27 20:57 >>why TCheckedList returns lists ? it's I wrote only for example, on quick hand.  My code implementation is define the class, inherited from TStringList: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i TMyClass=class(TStringList)  Checked:TBoolList;  Founded:TBoolList;  end;  But writing something like: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i m:TMyClass; m[i]:='aaa';m.Checked[i]:=True; // looks bad for me //  I would prefer to write:m[i].Checked:=True;  is it possible to achieve? ---------------------------------------------------------------------- skalogryz · 2016-03-27 21:29 Quote from: staratel20 on March 27, 2016, 10:57:54 pmis it possible to achieve? Yes. You'll have to use FPC 3.0.x. Won't work with FPC 2.6.4 ---------------------------------------------------------------------- staratel20 · 2016-03-27 22:06 I use FPC 3.0, can you give me a pair lines of code how to do this? ---------------------------------------------------------------------- skalogryz · 2016-03-27 22:20 Quote from: staratel20 on March 28, 2016, 12:06:23 amI use FPC 3.0, can you give me a pair lines of code how to do this? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$mode objfpc}{$modeswitch advancedrecords} uses   StrUtils, Classes; type  TBoolList = array of Boolean; // whatever. doesn't have to be the dynamic array type   TMyClass = class;   _MyClassInternal = record  private    function GetChecked: Boolean;     procedure SetChecked(AChecked: Boolean);  public    idx : integer;    cl  : TMYClass;    t   : string;    property Checked: Boolean read GetChecked write SetChecked;  end;    TMyClass = class(TStringList)   protected    function GetIntItem(aidx: Integer): _MyClassInternal;    procedure SetIntItem(aidx: integer; const m: _MyClassInternal);  public    Checked: TBoolList;    Founded: TBoolList;    property Items[i: integer]: _MyClassInternal read GetIntItem write SetIntItem; default;  end;   operator := (s : string) m : _MyClassInternal;begin  m.t:=s;  end; procedure TMyClass.SetIntItem(aidx: integer; const m: _MyClassInternal);begin  Strings[aidx]:=m.t;end; function _MyClassInternal.GetChecked: Boolean; begin   Result:=cl.Checked[idx];end; procedure _MyClassInternal.SetChecked(AChecked: Boolean);begin  cl.Checked[idx]:=AChecked;end;  function TMyClass.GetIntItem(aidx: Integer): _MyClassInternal;begin  Result.idx:=aidx;  Result.cl:=Self;end; var  m :  TMyClass;begin  m:=TMyClass.Create;  // just init   m.Add('');  SetLength(m.Checked, 1);   SetLength(m.Founded, 1);   m[0]:='hello world';  writeln(m[0].checked);  m[0].checked:=true;  writeln(m[0].checked);  writeln(m.strings[0]);end. ---------------------------------------------------------------------- staratel20 · 2016-03-27 22:24 skalogryz: Very, very thank you. Thaddy: I really try it by myself before you done, but unsuccessfully : ). marcov: can you please rename the topic subject to "Simulation overloaded properties in Lazarus, helper classes" for better index it in google? ---------------------------------------------------------------------- skalogryz · 2016-03-27 22:33 Quote from: staratel20 on March 28, 2016, 12:24:58 amskalogryz: Very, very thank you. if you ask my opinion, I cry tears of blood when I see code like this. To mitigate my statement above, I can add that if a feature is available in the language, it doesn't mean it has to be used right away. ---------------------------------------------------------------------- skalogryz · 2016-03-27 22:36 Quote from: staratel20 on March 28, 2016, 12:24:58 ammarcov: can you please rename the topic subject to "Simulation overloaded properties in Lazarus, helper classes" for better index it in google? the subject: "Synchronous" property problem doesn't reflect the proposed solution. That's why marcov suggested to change the subject. Thus any other person who would google for words "properties" "helpers" "freepascal" will run into this forum thread. You can change the subject my editing your first post in this thread. ---------------------------------------------------------------------- staratel20 · 2016-03-27 22:58 QuoteTo mitigate my statement above, I can add that if a feature is available in the language, it doesn't mean it has to be used right away.not understand you clean. Only suspect that you say(in another words): QuoteMy code not looks good. With future FPC progress code may looks significant better. I not recommend you to use it right now. Am I understand you correct? ---------------------------------------------------------------------- skalogryz · 2016-03-27 23:05 Quote from: staratel20 on March 28, 2016, 12:58:56 amQuoteMy code not looks good. With future FPC progress code may looks significant better. I not recommend you to use it right now. Am I understand you correct? No. Don't chase the sugar syntax at all. Don't chase java, javascript or C#. It's pascal. It's closer to asm and C, where code efficiency is preferred over fancy looking dotted notation. If you stop chasing the sugar syntax, it's very likely you'll no longer be dependent on the latest features of the compiler. ---------------------------------------------------------------------- staratel20 · 2016-03-28 07:05 QuoteNo. Don't chase the sugar syntax at all. Don't chase java, javascript or C#.I'm even don't thinking about it, I promise. And I don't  want Pascal to looks like Java or something else. I'm only want for to syntax of Pascal stay looks clean and human-friendly. And also follow the principle - don't produce redundant essence(but it wish closer to topic about overloaded properties). Maybe you also hint me that I construct bad classes hierarchy(because if don't - so in fact you say - you task can be done only with code, that makes my eyes bleeding  ). And maybe - you right, To know it for sure, let me explain. In fact I try to build dynamic array of structures: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i TMyItem=record  Data:string;  Checked:boolean;  Founded:boolean;end; TListMyItem=class  property Items[AIndex:integer]:TMyItem read GetMyItem;end; L:TListMyItem; // and now correct:L.Items[0].Data:='str';L.Items[0].Checked:=True; // but I wand have ability to write:L.Items[0]:='str';L.Items[0].Checked:=True; This effect can be reached  if only records support 'default', but it's not support. If I'm write: QuoteTMyItem=record   Data:string;default;   Checked:boolean;   Founded:boolean; end; I've got error. Also if I go this way - I need to do all from scratch without using of already complete classes like TStringList and TBoolList. ---------------------------------------------------------------------- skalogryz · 2016-03-28 09:52 Quote from: staratel20 on March 28, 2016, 09:05:17 amThis effect can be reached  if only records support 'default', but it's not support. If I'm write: QuoteTMyItem=record   Data:string;default;   Checked:boolean;   Founded:boolean; end; I've got error. Also if I go this way - I need to do all from scratch without using of already complete classes like TStringList and TBoolList. You can do that, if you overload assignment operator. But you don't want to do that, because it breaks TMyItem interface consistency. There're 3 attributes (Data, Checked, Founded) in the interface so far. And the consistent way, is when you access each attribute by its name. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i b[i].Data:='123123'b[i].Checked:=true;b[i].Founded:=true;  What you're asking for is to break the consistency (not every attribute is accessed by its name) and even introduce duplication (where .Data could be access by either explicit name or by unnamed (default) operation) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i b[i]:='123123';b[i].Data:='123123'; The only benefit from that is you need to type 5 characters less. It doesn't make the code more human-readable. Instead it might look puzzling, since exactly the same operation could be done in two different ways. And the code reader/maintainer has to keep in mind that .Data might be changed in a different way. The less duplication - the better. ---------------------------------------------------------------------- staratel20 · 2016-03-28 15:03 QuoteIt doesn't make the code more human-readable.By this logic default property - makes code more puzzling too, because after definition you can write: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Items.Item[i]:='aaa';Items[i]:='aaa';  and at this time this syntax not confused anyone. Want to thank you about the article about operators, I'll read it carefully.