Recent

Author Topic: [SOLVED] Stuck with TRegExprReplaceFunction  (Read 700 times)

AxBen

  • New Member
  • *
  • Posts: 17
[SOLVED] Stuck with TRegExprReplaceFunction
« on: March 01, 2024, 08:51:12 am »
I'm trying to implement a function that satisfies the requirements for RegExpr's ReplaceEx() method, but which I - sad to mention ;-) - seem to fail...

Code: Pascal  [Select][+][-]
  1. function ReplaceEsc(str: TRegExpr): UnicodeString;
  2. begin
  3.    ...
  4. end;
  5.  
  6. function ...;
  7. var
  8.    re: TRegExpr;
  9.    fp: TRegExprReplaceFunction;
  10.  
  11. begin
  12.    re := TRegExpr.Create('(?i)%[0-9a-f]{2}')
  13.    fp := @ReplaceEsc;
  14.  
  15.    Result := re.ReplaceEx(Result, fp);
  16. end;
  17.  

I keep getting this error:

Quote
Error: (4001) Incompatible types: got "Pointer" expected "<procedure variable type of function(TRegExpr):UnicodeString(1200) of object;Register>"

Any help is highly appreciated...
« Last Edit: March 01, 2024, 02:03:54 pm by AxBen »

AlexTP

  • Hero Member
  • *****
  • Posts: 2526
    • UVviewsoft
Re: Stuck with TRegExprReplaceFunction
« Reply #1 on: March 01, 2024, 08:54:33 am »
you created callback with wrong type. it must be "<procedure variable type of function(TRegExpr):UnicodeString(1200) of object;Register> ie it must be method of some object.

TRon

  • Hero Member
  • *****
  • Posts: 3930
Re: Stuck with TRegExprReplaceFunction
« Reply #2 on: March 01, 2024, 09:12:16 am »

Quote
Error: (4001) Incompatible types: got "Pointer" expected "<procedure variable type of function(TRegExpr):UnicodeString(1200) of object;Register>"

Any help is highly appreciated...
AlexTP did a splendid job though you might (still) be (a bit) confused (since you seem new to the game).

The bold part of the error message is the hint, AlexTP provided the hint on what you should do, and I present a how that might look:
Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. // references:
  6. // https://forum.lazarus.freepascal.org/index.php/topic,66443.0.html
  7. // https://www.freepascal.org/docs-html/ref/refse28.html
  8.  
  9. uses
  10.   regexpr;
  11.  
  12. type
  13.   TMethods = object
  14.     function ReplaceEsc(str: TRegExpr): string;  // this is a function declared inside an object which is then referred to as a method aka procedure/function /of object/.
  15.   end;
  16.  
  17. var
  18.   Methods : TMethods;
  19.  
  20. function TMethods.ReplaceEsc(str: TRegExpr): string;
  21. begin
  22. //   ...
  23. end;
  24.  
  25. function dodo: string;
  26. var
  27.    re: TRegExpr;
  28.    fp: TRegExprReplaceFunction;
  29. begin
  30.    re := TRegExpr.Create('(?i)%[0-9a-f]{2}');
  31.    fp := @Methods.ReplaceEsc;
  32.  
  33.    Result := re.ReplaceEx(Result, fp);
  34.    // which is the same as:
  35.    // Result := re.ReplaceEx(Result, @Methods.ReplaceEsc);
  36. end;
  37.  
  38. begin
  39.   dodo;
  40. end.
  41.  
« Last Edit: March 01, 2024, 09:21:16 am by TRon »
I do not have to remember anything anymore thanks to total-recall.

AxBen

  • New Member
  • *
  • Posts: 17
Re: Stuck with TRegExprReplaceFunction
« Reply #3 on: March 01, 2024, 02:03:39 pm »
@TRon, thank you, I got it working.

Coming from C, I find that there's quite a lot of overhead here...  :'(

TRon

  • Hero Member
  • *****
  • Posts: 3930
Re: Stuck with TRegExprReplaceFunction
« Reply #4 on: March 01, 2024, 02:12:38 pm »
@TRon, thank you, I got it working.
You're welcome. Thank you for reporting back.

Quote
Coming from C, I find that there's quite a lot of overhead here...  :'(
Actually using the old school object is the least overhead  :)

Usually you use a class for that, and in case you are developing a gui application (Lazarus) then this is not a real problem because you already have a f.i. a form (to which you can add your ReplaceEsc method.

But... this is all related to how the/a object ( TRegExpr in this particular case ) implemented the callback. In this particular case it is a method but it could just as well have been a regular procedure or function (which would then not require the overhead of instantiating a class). To make matters even more complicated you could also use a static method of a class (which does not have to instantiated).

I hope I did not add more to the confusion (in case there was any to begin with ofc.)  :)

edit: add example:
This is how confusion could look like:
Code: Pascal  [Select][+][-]
  1. program confucius;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5.  
  6. // class TMyClass
  7.  
  8. type
  9.   TCallbackMethod = procedure(x: integer) of object;
  10.   TCallbackProc   = procedure(x: integer);
  11.  
  12.   TMyClass = class
  13.     class procedure Callback(x: integer); static;
  14.     procedure AnotherCallBack(x: integer);
  15.   end;
  16.  
  17.  
  18. class procedure TMyClass.Callback(x: integer);
  19. begin
  20.   writeln(x);
  21. end;
  22.  
  23. procedure TMyClass.AnotherCallback(x: integer);
  24. begin
  25.   writeln(x);
  26. end;
  27.  
  28.  
  29. // old style object TMethods
  30.  
  31. type
  32.   TMethods = object
  33.     procedure callback(x: integer);
  34.   end;
  35.  
  36.  
  37. procedure TMethods.Callback(x: integer);
  38. begin
  39.   writeln(x);
  40. end;
  41.  
  42.  
  43. // regular procedure
  44.  
  45. procedure Callback(x: integer);
  46. begin
  47.   writeln(x);
  48. end;
  49.  
  50.  
  51.  
  52.  
  53. procedure SomethingWithACallback(cbMethod: TCallBackMethod; cbProc: TCallbackProc);
  54. begin
  55.   if assigned(cbMethod) then cbMethod(10);
  56.   if assigned(cbProc) then cbProc(11);
  57. end;
  58.  
  59.  
  60. var
  61.   Methods : TMethods;
  62.   MyClass : TMyClass;
  63.  
  64. begin
  65.   writeln(1);
  66.   SomethingWithACallback(@Methods.Callback ,@Callback);
  67.   writeln(2);
  68.   SomethingWithACallback(nil ,@TMyClass.Callback);
  69.   writeln(3);
  70.   MyClass := TMyClass.Create;
  71.   SomethingWithACallback(@MyClass.AnotherCallback ,nil);
  72.   MyClass.Free;
  73. end.
  74.  

And to make it even more fun, anonymous functions are in the makings :)
« Last Edit: March 01, 2024, 02:46:47 pm by TRon »
I do not have to remember anything anymore thanks to total-recall.

 

TinyPortal © 2005-2018