Recent

Author Topic: [SOLVED] Helpers  (Read 5885 times)

pmesquita

  • Jr. Member
  • **
  • Posts: 62
[SOLVED] Helpers
« on: June 25, 2021, 08:08:09 pm »
Guys..

I have a silly problem that is making me stuck ..
I created a Helper for the Integer type, but when I add a unit where I need to use the functions... the compiled doesn't find the function...

Code: Pascal  [Select][+][-]
  1. unit Helpers.SysUtils;
  2.  
  3. {$MODE OBJFPC}{$H+}
  4. {$MODESWITCH TYPEHELPERS}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils;
  10.  
  11. Type
  12.   { HelperInt }
  13.   HelperInt = Type Helper for Integer
  14.  
  15.   Public
  16.     Function SecsToDateTime(ASecs: Integer): String;
  17.   End;
  18.  
  19.  
  20. implementation
  21.  
  22. { HelperInt }
  23. Function HelperInt.SecsToDateTime(ASecs: Integer): String;
  24. Var
  25.   LDays, LHours, LMins, LSecs: Integer;
  26.  Begin
  27.   Result:= '-';
  28.   If (ASecs > 0) Then
  29.    Begin
  30.     LDays:= ASecs div SecsPerDay;
  31.     ASecs:= ASecs mod SecsPerDay;
  32.  
  33.     LHours:= ASecs div SecsPerHour;
  34.     ASecs:=  ASecs mod SecsPerHour;
  35.  
  36.     LMins:= ASecs div SecsPerMin;
  37.     ASecs:= ASecs mod SecsPerMin;
  38.  
  39.     LSecs := ASecs;
  40.  
  41.     Result:= Format('%d day(s) %.2d:%.2d:%.2d', [LDays, LHours, LMins, LSecs]);
  42.    End;
  43.  End;
  44.  
  45. End.
  46.  


any tips.. ?
« Last Edit: June 26, 2021, 03:05:40 pm by pmesquita »

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Helpers
« Reply #1 on: June 25, 2021, 08:21:25 pm »
the compiled doesn't find the function...
any tips.. ?
Need an example. It works without any problems:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$LONGSTRINGS ON}
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses Helpers.SysUtils;
  6.  
  7. var
  8.   i: Integer;
  9. begin
  10.   i := 100;
  11.   Writeln(i.SecsToDateTime(i));
  12.   Readln;
  13. end.

pmesquita

  • Jr. Member
  • **
  • Posts: 62
Re: Helpers
« Reply #2 on: June 25, 2021, 09:00:09 pm »
So..

I really don't understand why it isn't working..
what I believe it to be is: in unit1(which is a project unit) I'm using {$MODE DELPHI} because I need to use the TObjectHashMap<String, String> object);
Code: Pascal  [Select][+][-]
  1. Procedure FormLoadGrid(ARow: Integer; AValues: TObjectHashMap<String, String>);
  to send some values between functions and without DELPHI mode, the compiler complains:

Error: Generics without specialization cannot be used as a type for a variable

but using {$MODE DELPHI} everything works perfectly...

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Helpers
« Reply #3 on: June 25, 2021, 09:10:41 pm »
I really don't understand why it isn't working..
You still haven't provided the part of the code with the error.

what I believe it to be is: in unit1(which is a project unit) I'm using {$MODE DELPHI} because I need to use the TObjectHashMap<String, String> object);
Code: Pascal  [Select][+][-]
  1. Procedure FormLoadGrid(ARow: Integer; AValues: TObjectHashMap<String, String>);
  to send some values between functions and without DELPHI mode, the compiler complains:
Error: Generics without specialization cannot be used as a type for a variable
This is another question, but I will answer it. Because in FPC mode, as the compiler indicated, you need to use specialize:
Code: Pascal  [Select][+][-]
  1. procedure FormLoadGrid(ARow: Integer; AValues: specialize TObjectHashMap<string, string>);

pmesquita

  • Jr. Member
  • **
  • Posts: 62
Re: Helpers
« Reply #4 on: June 25, 2021, 09:36:10 pm »
Quote
You still haven't provided the part of the code with the error.


Code: Pascal  [Select][+][-]
  1. Procedure FormLoadGrid(ARow: Integer; AValues: specialize TObjectHashMap<String, String>);
  2.  Begin
  3.   If (ARow = 0) Then
  4.    ARow:= NewGrid01.AddRows();
  5.  
  6.   TMainForm.NewGrid01.Cells[FIELD1, ARow]:= AValues.Items['FIELD1'];
  7.   TMainForm.NewGrid01.Cells[FIELD2, ARow]:= AValues.Items['FIELD2'];
  8.         .
  9.         .
  10.         .
  11.         .
  12.   TMainForm.NewGrid01.Cells[FIELD3, ARow]:= StrToInt(AValues.Items['FIELD3']).SecsToDateTime
  13.  
  14.  
  15.  End;
  16.  

Basic is .. in the X button's onclick event I have the routine:

Code: Pascal  [Select][+][-]
  1. Var
  2.   LGridValues    : specialize TObjectHashMap<String, String>;      
  3.  Begin
  4.   LGridValues:= TObjectHashMap<String, String>.Create;
  5.   Try
  6.     LGridValues.Add('FIELD1', LSQLID.ToString);
  7.     LGridValues.Add('FIELD2',   FormatDateTime('dd/mm/yyyy hh:nn', TMainForm.EditDateTime02.DateTime));
  8.     LGridValues.Add('FIELD3', VarToStr(ZeosQuery.FieldValues['FIELD3']));
  9.     TMainForm.FormLoadGrid(GSelectedRow, LGridValues);  
  10.   Finally
  11.    FreeAndNil(LGridValues);
  12.   End;
  13.  End;

"NewGrid01" is another component of mine that is an inheritance from TStrinGrid with some more functions...


Quote
This is another question, but I will answer it. Because in FPC mode, as the compiler indicated, you need to use specialize:

Understood, I'll read about this later...





ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Helpers
« Reply #5 on: June 25, 2021, 10:07:12 pm »
Code: Pascal  [Select][+][-]
  1. ...
  2.     TMainForm.FormLoadGrid(GSelectedRow, LGridValues);  
  3.  
TMainForm is variable? What message does the compiler output?

pmesquita

  • Jr. Member
  • **
  • Posts: 62
Re: Helpers
« Reply #6 on: June 26, 2021, 01:46:33 am »
Code: Pascal  [Select][+][-]
  1. ...
  2.     TMainForm.FormLoadGrid(GSelectedRow, LGridValues);  
  3.  
TMainForm is variable? What message does the compiler output?

Yes, its from

Code: Pascal  [Select][+][-]
  1. Var
  2.   TMainForm: TTMainForm;
  3.  

Compiler output:

Code: Pascal  [Select][+][-]
  1. Error: Illegal qualifier

But if I type StrToInt(AValues.Items['FIELD3']).<And press Ctrl + Space>) the code completion is displayed but the helper I created doesn't appear...

I was including the Helpers.SysUtils unit in the uses above the Interface, now I've moved it to the Implementation uses and the "Code Completion" "Find" the helper, however when compiling all the lines of code that use Helper (mostly it is : Variable-Integer.ToString ) is showing the same message:


speter

  • Sr. Member
  • ****
  • Posts: 349
Re: Helpers
« Reply #7 on: June 26, 2021, 02:35:33 am »
Code: Pascal  [Select][+][-]
  1. ...
  2.     TMainForm.FormLoadGrid(GSelectedRow, LGridValues);  
  3.  
TMainForm is variable? What message does the compiler output?

Yes, its from

Surely (as ASerge is suggesting) your form variable is "MainForm" (of type TMainForm)!?

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

pmesquita

  • Jr. Member
  • **
  • Posts: 62
Re: Helpers
« Reply #8 on: June 26, 2021, 02:53:39 am »
No..
no... is it TMainForm of type TTMainForm

Code: Pascal  [Select][+][-]
  1. Var
  2.   TMainForm: TTMainForm;

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: Helpers
« Reply #9 on: June 26, 2021, 11:02:10 am »
I was including the Helpers.SysUtils unit in the uses above the Interface, now I've moved it to the Implementation uses and the "Code Completion" "Find" the helper, however when compiling all the lines of code that use Helper (mostly it is : Variable-Integer.ToString ) is showing the same message:

Only one helper can be active for a type at the same time. So depending on the order of your uses sections you'll either get the helper from your Helpers.SysUtils unit or that from unit SysUtils (the last one will be picked). You can avoid this by inheriting your HelperInt from TLongIntHelper like in the following example and then making sure your Helpers.SysUtils units is used after the SysUtils unit:

Code: Pascal  [Select][+][-]
  1. type
  2.   MyHelper = type helper(TIntegerHelper) for Integer
  3.   // ...

(Note: In FPC trunk one can also use the modeswitch MultiHelpers to allow for multpile helpers of the same type without the need to use inheritance, though the released FPC versions do not support that)

Sidenote: Why do you pass the seconds as argument to your helper? You can drop that parameter and simply use Self which will be the value (or variable) you called the helper method on.

pmesquita

  • Jr. Member
  • **
  • Posts: 62
Re: Helpers
« Reply #10 on: June 26, 2021, 02:55:19 pm »
Quote
Only one helper can be active for a type at the same time. So depending on the order of your uses sections you'll either get the helper from your Helpers.SysUtils unit or that from unit SysUtils (the last one will be picked). You can avoid this by inheriting your HelperInt from TLongIntHelper like in the following example and then making sure your Helpers.SysUtils units is used after the SysUtils unit:

Of course, now I'm thinking here and obviously you're right. In my case I inherited the TIntegerHelper and changed the uses so that my helper's unit is last and everything worked perfectly..

I had already played a little with the helpers but nothing that I needed to implement in any project...

But thanks for everyone's help...

Long live Lazarus/FPC
« Last Edit: June 26, 2021, 03:05:27 pm by pmesquita »

 

TinyPortal © 2005-2018