Using dynamic array constructors lazarus / 62-General ---------------------------------------------------------------------- howardpc · 2016-07-03 14:29 The introduction of a Delphi-compatible class-like constructor syntax in FPC 3.0.0    http://wiki.freepascal.org/FPC_New_Features_3.0#Dynamic_array_const ructors is very welcome. Is it possible to pass values to such a constructor dynamically (i.e. not by typing literal values and commas into a source code editor)? ---------------------------------------------------------------------- Leledumbo · 2016-07-03 15:17 Do you have any example wish of how it should be done? i.e.: an uncertain-to-work code you would like to type. Probably you just need System.Copy. ---------------------------------------------------------------------- Thaddy · 2016-07-03 15:29 Urhm. Asking about scripting language features? But anyway. Do you have an example in a comparable language like C or C++? Or some pseudo code of what you envisage? ---------------------------------------------------------------------- howardpc · 2016-07-03 18:24 I was looking for something that would interpret a comma-separated list as a list of successive values in the array to be initialized. Perhaps the following short example explains what I am after: 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 program Project1; {$H+} type  TStringDynArray = array of ansistring; const  NumberStr = 'zero,one,two,three,four,five,six,seven'; var  nums: TStringDynArray;  idx: integer = 0;  s: ansistring;begin  // initialize array  nums:=TStringDynArray.create(NumberStr);  // display array value(s)  for s in nums do begin    WriteLn('Index:',idx,' ',s);    Inc(idx);  end;end. Compare this with the constructor 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 nums:=TStri ngDynArray.create('zero','one','two','three','four','five','six','seve n'); ---------------------------------------------------------------------- Bart · 2016-07-03 18:38 How can the compiler ever know what you mean then? Should it treat numberstring as one string (why should not the array of strig contain a stringwith a comma), or as a commaseparated list? Bart ---------------------------------------------------------------------- molly · 2016-07-03 19:48 You are absolutely right there Bart but, in the quest to instruct the compiler to be able to do the right thing there: Code: [Select]const   NumberStrings = 'one', 'two'; Which produces a: QuoteFatal: Syntax error, ";" expected but "," found or perhaps more accurate: Code: [Select]const   NumberStrings = ('one', 'two'); Which produces a: QuoteFatal: Syntax error, ")" expected but "," found The way it's currently suppose to be: Code: [Select]Const   NumConst : Array[0..1] of ansistring = ('zero','one'); or: Code: [Select]Var   NumVar   : array[0..1] of ansistring = ('zero','one'); Maybe that is what howardpc (in basics) is/was referring to ? ---------------------------------------------------------------------- molly · 2016-07-03 20:52 Nevermind. Something like this seems to do what was asked for: 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 program arrayhelper; {$MODE OBJFPC}{$MODESWITCH TYPEHELPERS} Uses  StrUtils; type  TStringDynArray = array of ansistring; type  TStringDynArrayHelper = type helper for TStringDynArray    class function CreateFromDelimitedString(DelimString: String): TStringDynArray static;  end; class function TStringDynArrayHelper.CreateFromDelimitedString(DelimString: String): TStringDynArray;var  num, i : Integer;begin  num := WordCount(DelimString, [',']);  SetLength(Result, num);  for i := 1 to num do  begin    Result[i-1] := ExtractWord(i, DelimString, [',']);  end;end; const  NumberStr = 'zero,one,two,three,four,five,six,seven';var  nums  : TStringDynArray;  idx   : integer = 0;  s     : ansistring;begin  // initialize array//  nums:=TStringDynArray.create(NumberStr);  nums:=TStringDynArray.CreateFromDelimitedString(NumberStr);   // display array value(s)  for s in nums do begin    WriteLn('Index:',idx,' ',s);    Inc(idx);  end;end. ---------------------------------------------------------------------- ArtLogi · 2016-07-03 21:14 Molly how you can do the word extracting without passing the character beforehand in the variable of the type of TSysCharSet? Is the key those square brackets? I did fight "days" before getting it right in FPC2.6.xx ---------------------------------------------------------------------- molly · 2016-07-03 21:33 Quote from: ArtLogi on July 03, 2016, 11:14:28 pmMolly how you can do the word extracting without passing the character beforehand in the variable of the type of TSysCharSet? Is the key those square brackets? I did fight "days" before getting it right in FPC2.6.xx Well, it is working for me since i can remember (but, i have bad memory  ). Maybe this will be able to help you ? Code: [Select]program passer; {$MODE OBJFPC}{$H+} Uses   SysUtils, StrUtils; Const   LowChars  = ['a'..'z']; var   HighChars : TSysCharset = ['A'..'Z'];   num       : integer;   S         : String; begin   S := 'I stand amid the roar of a surf-tormented shore, and 1 hold within my hand Grains of the golden sand';   num := wordcount(S, []);   Writeln('num 0 = ', num);   num := wordcount(S, LowChars);   Writeln('num 1 = ', num);   num := wordcount(S, HighChars);   Writeln('num 2 = ', num);   HighChars := ['a','b',','];   num := wordcount(S, HighChars);   Writeln('num 3 = ', num);   include(highChars, ' ');   num := wordcount(S, HighChars);   Writeln('num 4 = ', num);     HighChars := HighChars + ['1','2'];   num := wordcount(S, HighChars);   Writeln('num 5 = ', num); end. Also have a look at set operators. ---------------------------------------------------------------------- howardpc · 2016-07-03 21:39 Many thanks, molly. I prefer a helper with no dependency on StrUtils. 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 TStringDynArrayHelper = type helper for TStringDynArray    class function CreateCommaDelimited(const aCommaString: string): TStringDynArray; static;  end; class function TStringDynArrayHelper.CreateCommaDelimited(const aCommaString: string): TStringDynArray;var  p: integer = 1;  len: integer = 0;  predLen: integer;  s: string;begin  if (aCommaString = '') then    Exit(nil);  repeat    s:='';    while (p <= Length(aCommaString)) and (aCommaString[p] <> ',') do begin      s:=s + aCommaString[p];      Inc(p);    end;    predLen:=len;    Inc(len);    SetLength(Result, len);    Result[predLen]:=s;    Inc(p);  until (p > Length(aCommaString));end; ---------------------------------------------------------------------- molly · 2016-07-03 23:19 Quote from: howardpc on July 03, 2016, 11:39:22 pmI prefer a helper with no dependency on StrUtils. Ah, indeed. i was being lazy  As a matter of fact so lazy that i don't even wanted to use a type helper  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 program arraymore; {$MODE OBJFPC} {.$DEFINE USETYPEHELPERS}{$IFDEF USETYPEHELPERS}  {$MODESWITCH TYPEHELPERS}{$ENDIF} Uses  Heaptrc, StrUtils; type  TStringDynArray = array of ansistring; {$IFDEF USETYPEHELPERS} type  TStringDynArrayHelper = type helper for TStringDynArray    class function CreateFromDelimitedString(DelimString: String): TStringDynArray static;  end; class function TStringDynArrayHelper.CreateFromDelimitedString(DelimString: String): TStringDynArray;var  num, i : Integer;begin  num := WordCount(DelimString, [',']);  SetLength(Result, num);  for i := 1 to num do  begin    Result[i-1] := ExtractWord(i, DelimString, [',']);  end;end; operator := (S : string): TStringDynArray;begin  Result := TStringDynArray.CreateFromDelimitedString(S);end; {$ELSE} operator := (S : string): TStringDynArray;var  num, i : Integer;begin  num := WordCount(S, [',']);  SetLength(Result, num);  for i := 1 to num do  begin    Result[i-1] := ExtractWord(i, S, [',']);  end;end; {$ENDIF}  const  NumberStr = 'zero,one,two,three,four,five,six,seven';var  nums  : TStringDynArray;  idx   : integer = 0;  s     : ansistring;begin  // initialize array//  nums:=TStringDynArray.create(NumberStr);//  nums:=TStringDynArray.CreateFromDelimitedString(NumberStr);   nums := NumberStr;   // display array value(s)  for s in nums do begin    WriteLn('Index:',idx,' ',s);    Inc(idx);  end;end.  Mind-boggling in case you use these kind of things to much/deep. Edit: Hmz, seems i misunderstood something ?: Code: [Select]const   NumberStr = 'zero,one,two,three,four,five,six,seven'; var   nums  : TStringDynArray = NumberStr; produces: Quote  Fatal: Syntax error, "NIL" expected but "identifier NUMBERSTR" found Is that not considered an assignment ? In which case it should be covered by the explicit assignment operator ? If not the case, is there a separate operator for such assignments ? (i was unable to find in the docs) ---------------------------------------------------------------------- howardpc · 2016-07-04 06:44 Well 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 nums: TStringDynArray = NumberString;is of course an assignment combined with a declaration. However it does not use the ':=' operator you have defined, so the compiler rightly complains that the two types are incompatible. BTW, do you know if recent Delphis now allow that C-style initialization syntax in the declaration of variables? ---------------------------------------------------------------------- molly · 2016-07-04 07:07 Quote from: howardpc on July 04, 2016, 08:44:55 amBTW, do you know if recent Delphis now allow that C-style initialization syntax in the declaration of variables? I have honestly no idea (we haven't used Delphi in ages). But, i fully understand the desire to have such support. In fact i would already settle for getting rid of the requirement to declare the size of the array for a variable/constant. e.g. var x: TStringDynArray = ('One','Two');. TBH, for me the desire comes from porting c-code. so for me .. uh .. it's about laziness ---------------------------------------------------------------------- ArtLogi · 2016-07-28 17:25 It's allways the laziness ---------------------------------------------------------------------- Thaddy · 2016-07-28 17:47 Quote from: howardpc on July 04, 2016, 08:44:55 amBTW, do you know if recent Delphis now allow that C-style initialization syntax in the declaration of variables? If you mean: 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 program a;{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}{$APPTYPE CONSOLE}var a:integer = 1;begin  ..do something with aend. The answer is yes... If you mean: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 program b;{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}{$APPTYPE CONSOLE}begin with var a =1 do //declarations on the fly   begin   inc(a); end; end. The answer is no, and I hope that never happens... as a language construct: You will loose structure and oversight and your code becomes hard to read for mere mortals. Note the Delphi IDE has some support for things like that, but that is not a language feature, but a refactoring/codecompletion feature of the IDE.