Recent

Author Topic: Do array properties support var indexes?  (Read 1754 times)

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1465
    • Lebeau Software
Do array properties support var indexes?
« on: February 13, 2024, 07:25:32 pm »
I came across an interesting tidbit of code today that uses an array property with a var index that is incremented in the getter.  Does FreePascal support this? If so, how far back?

Code: Pascal  [Select][+][-]
  1. type
  2.   TTest = class
  3.   protected
  4.     function GetValueFromIndex(var Index: Integer): string;
  5.     procedure SetValueFromIndex(var Index: Integer; const S: string);
  6.   public
  7.     property ValueFromIndex[var Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;
  8.   end;
  9.  
  10. function TTest.GetValueFromIndex(var Index: Integer): String;
  11. begin
  12.   Result := ...; // get data for index...
  13.   Inc(Index); // may be more than 1...
  14. end;
  15.  
  16. procedure TTest.SetValueFromIndex(var Index: Integer; const S: String);
  17. begin
  18.   // set data for index...
  19. end;
  20.  
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

alpine

  • Hero Member
  • *****
  • Posts: 1347
Re: Do array properties support var indexes?
« Reply #1 on: February 13, 2024, 07:34:22 pm »
I wouldn't expect the index to change in that context. What could be the use of this?
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1465
    • Lebeau Software
Re: Do array properties support var indexes?
« Reply #2 on: February 13, 2024, 08:13:34 pm »
I wouldn't expect the index to change in that context. What could be the use of this?

In this particular situation, it is to support iteration of a string list where a given item might span multiple strings. The caller's loop index would have to be incremented by however many strings were actually read per item.

Here is a closer example to the real use-case:

Code: Pascal  [Select][+][-]
  1. type
  2.   THeaderList = class(TStringList)
  3.   protected
  4.     ...
  5.     function GetValueFromIndex(var Index: Integer): string;
  6.     procedure SetValueFromIndex(var Index: Integer; const S: string);
  7.   public
  8.     ...
  9.     property ValueFromIndex[var Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;
  10.   end;
  11.      
  12. ...
  13.  
  14. function THeaderList.GetValueFromIndex(var Index: Integer): string;
  15. var
  16.   S: string;
  17. begin
  18.   Result := '';
  19.   if (Index < 0) or (Index >= Count) then Exit;
  20.   Result := Strings[Index];
  21.   Inc(Index);
  22.   if (Some Condition) then
  23.   begin
  24.     while Index < Count do
  25.     begin
  26.       S := Strings[Index];
  27.       if (Some other condition) then Break;
  28.       Result := Result + S;
  29.       Inc(Index);
  30.     end;
  31.   end;
  32. end;
  33.      
  34. procedure THeaderList.SetValueFromIndex(var Index: Integer; const S: String);
  35. begin
  36.   if S <> '' then
  37.   begin
  38.     if Index < 0 then Index := Add('');
  39.     if (Some Condition) then
  40.     begin
  41.       // delete additional strings after Index...
  42.       // split up S and add/insert into the list starting at Index...
  43.     end else
  44.       Strings[Index] := S;
  45.   end
  46.   else if Index >= 0 then
  47.   begin
  48.     if (Some Condition) then begin
  49.       // delete additional strings after Index...
  50.     end;
  51.     Delete(Index);
  52.   end;
  53. end;
  54.  

Code: Pascal  [Select][+][-]
  1. var
  2.   Headers: THeaderList;
  3.   Index: Integer;
  4.   s: String;
  5. begin
  6.   ...
  7.   Index := 0;
  8.   while Index < Headers.Count do
  9.   begin
  10.     ...
  11.     S := Headers.ValueFromIndex[Index]; // increments Index as needed...
  12.     ...
  13.   end;
  14.   ...
  15. end;
  16.  

If you want more context:

https://en.delphipraxis.net/topic/11033-409-add-valuefromindex-property-to-tidheaderlist/
https://github.com/indySockets/indy/issues/408
https://github.com/indySockets/indy/issues/409

I'm not asking if this is a good design or not, only whether this property syntax will work or not.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

ASerge

  • Hero Member
  • *****
  • Posts: 2379
Re: Do array properties support var indexes?
« Reply #3 on: February 13, 2024, 08:44:16 pm »
I came across an interesting tidbit of code today that uses an array property with a var index that is incremented in the getter.  Does FreePascal support this? If so, how far back?
I suspect that appeared initially, at the same time as the indexed properties. For compatibility with Delphi.
An even more unusual example:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$APPTYPE CONSOLE}
  3.  
  4. type
  5.   TTest = class
  6.   private
  7.     function GetValue(out Index: Integer): string;
  8.   public
  9.     property Value[out Index: Integer]: string read GetValue; default;
  10.   end;
  11.  
  12. function TTest.GetValue(out Index: Integer): string;
  13. begin
  14.   Str(Index, Result);
  15.   Inc(Index);
  16. end;
  17.  
  18. var
  19.   Test: TTest;
  20.   i: Integer = 1;
  21. begin
  22.   Test := TTest.Create;
  23.   try
  24.     Writeln(Test[i]);
  25.     Writeln(Test[i]);
  26.     Writeln(Test[i]);
  27.   finally
  28.     Test.Free;
  29.   end;
  30.   Readln;
  31. end.
Using -gt (Trash variables) the output will be garbage.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10803
  • Debugger - SynEdit - and more
    • wiki
Re: Do array properties support var indexes?
« Reply #4 on: February 13, 2024, 10:57:40 pm »
Until it appears in documentation I wouldn't trust on it being future proof.

At some time you could pass properties to "inc" or "var param" if those properties referred to a field. This had turned out to be a bug, and was changed.

jamie

  • Hero Member
  • *****
  • Posts: 6801
Re: Do array properties support var indexes?
« Reply #5 on: February 13, 2024, 11:36:52 pm »
Interesting, I can see how that would work nicely for an auto-increment for a string search. At least it would place the index to the next possible search after the current found item.

 In any case, I can see it most likely does not accept a CONSTANT for an index value.
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 16520
  • Kallstadt seems a good place to evict Trump to.
Re: Do array properties support var indexes?
« Reply #6 on: February 14, 2024, 12:37:45 pm »
Until it appears in documentation I wouldn't trust on it being future proof.
The documentation only states that read/write access is only through getters and setters.
Getter and setter methods can use var, so it is  at least implied that should work for array properties too.
Aserge's example is a bit contrived since he well knows that -gt will trash the out parameter and it is documented that an out parameter not necessarily obeys when given an initial value.
https://www.freepascal.org/docs-html/ref/refsu66.html
« Last Edit: February 14, 2024, 12:44:52 pm by Thaddy »
But I am sure they don't want the Trumps back...

VisualLab

  • Hero Member
  • *****
  • Posts: 630
Re: Do array properties support var indexes?
« Reply #7 on: February 14, 2024, 08:11:30 pm »
I wouldn't expect the index to change in that context. What could be the use of this?

I'm also interested, what's the benefit?

In this particular situation, it is to support iteration of a string list where a given item might span multiple strings. The caller's loop index would have to be incremented by however many strings were actually read per item.

Here is a closer example to the real use-case:

Code: Pascal  [Select][+][-]
  1. type
  2.   THeaderList = class(TStringList)
  3.   protected
  4.     ...
  5.     function GetValueFromIndex(var Index: Integer): string;
  6.     procedure SetValueFromIndex(var Index: Integer; const S: string);
  7.   public
  8.     ...
  9.     property ValueFromIndex[var Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;
  10.   end;
  11.      
  12. ...
  13.  
  14. function THeaderList.GetValueFromIndex(var Index: Integer): string;
  15. var
  16.   S: string;
  17. begin
  18.   Result := '';
  19.   if (Index < 0) or (Index >= Count) then Exit;
  20.   Result := Strings[Index];
  21.   Inc(Index);
  22.   if (Some Condition) then
  23.   begin
  24.     while Index < Count do
  25.     begin
  26.       S := Strings[Index];
  27.       if (Some other condition) then Break;
  28.       Result := Result + S;
  29.       Inc(Index);
  30.     end;
  31.   end;
  32. end;
  33.      
  34. procedure THeaderList.SetValueFromIndex(var Index: Integer; const S: String);
  35. begin
  36.   if S <> '' then
  37.   begin
  38.     if Index < 0 then Index := Add('');
  39.     if (Some Condition) then
  40.     begin
  41.       // delete additional strings after Index...
  42.       // split up S and add/insert into the list starting at Index...
  43.     end else
  44.       Strings[Index] := S;
  45.   end
  46.   else if Index >= 0 then
  47.   begin
  48.     if (Some Condition) then begin
  49.       // delete additional strings after Index...
  50.     end;
  51.     Delete(Index);
  52.   end;
  53. end;
  54.  

Code: Pascal  [Select][+][-]
  1. var
  2.   Headers: THeaderList;
  3.   Index: Integer;
  4.   s: String;
  5. begin
  6.   ...
  7.   Index := 0;
  8.   while Index < Headers.Count do
  9.   begin
  10.     ...
  11.     S := Headers.ValueFromIndex[Index]; // increments Index as needed...
  12.     ...
  13.   end;
  14.   ...
  15. end;
  16.  

If you want more context:

https://en.delphipraxis.net/topic/11033-409-add-valuefromindex-property-to-tidheaderlist/
https://github.com/indySockets/indy/issues/408
https://github.com/indySockets/indy/issues/409

I'm not asking if this is a good design or not, only whether this property syntax will work or not.

Or maybe we should ask whether this is a good project?

I really don't see any tangible benefit in this. More like: fancy programming.

Moreover, what disadvantages could it have? Or what unforeseen consequences it may result in?

Thaddy

  • Hero Member
  • *****
  • Posts: 16520
  • Kallstadt seems a good place to evict Trump to.
Re: Do array properties support var indexes?
« Reply #8 on: February 14, 2024, 09:06:15 pm »
Practical example is e.g. a ledger where you change color between odd and even lines.
But I am sure they don't want the Trumps back...

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1465
    • Lebeau Software
Re: Do array properties support var indexes?
« Reply #9 on: February 16, 2024, 01:01:16 am »
Or maybe we should ask whether this is a good project?

That's is not what I'm looking for.  I just want to know if the syntax is valid or not.  I tried it in the latest Delphi and it works, but I don't have older Delphi versions to test with, or FreePascal for that matter.

Moreover, what disadvantages could it have? Or what unforeseen consequences it may result in?

As I explained earlier, while iterating this particular string list, there may be items in it that span across multiple strings, so a linear iteration of the list will have to skip strings at times, as individual strings won't be processable as-is but only when combined with related strings.  So, the caller's index would need to be updated by the appropriate number of strings that are to be skipped.

Obviously, there are better design choices, ie a dedicated extraction method (which actually does exist in the code), or a custom enumerator, etc, but that is not what I'm asking for in this situation.  I just want to know whether or not this syntax for index properties is supported by FreePascal.  Period.  I don't need a full discussion over this.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

jamie

  • Hero Member
  • *****
  • Posts: 6801
Re: Do array properties support var indexes?
« Reply #10 on: February 16, 2024, 01:41:41 am »
if it will make you feel better, I just tested this in D3 on my old Win2000 Pc. I had to blow the dust off it! %)

It is supported exactly the same way and works.

Thanks for bringing this to my attention. I never knew this existed because I never tried it but it's nice to know Delphi carries the torch for its surprising options.
The only true wisdom is knowing you know nothing

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1465
    • Lebeau Software
Re: Do array properties support var indexes?
« Reply #11 on: February 16, 2024, 07:16:48 pm »
if it will make you feel better, I just tested this in D3 on my old Win2000 Pc. I had to blow the dust off it! %)

It is supported exactly the same way and works.

Thank you, that is good to know!
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

TinyPortal © 2005-2018