Recent

Author Topic: Rosetta Code task  (Read 1150 times)

avk

  • Hero Member
  • *****
  • Posts: 752
Rosetta Code task
« on: October 11, 2022, 06:42:46 pm »
Hi all,

I met on Rosetta Code another interesting task that does not have a good solution in the Pascal/Object Pascal sections.
It seems that it can be solved using custom variants?

For example, in a separate unit:
Code: Pascal  [Select][+][-]
  1. unit my_obj;
  2. {$mode objfpc}{$H+}
  3. interface
  4.  
  5. uses
  6.   SysUtils, Variants;
  7.  
  8.   function NewMyObj: Variant;
  9.  
  10. implementation
  11. var
  12.   MyObjType: TInvokeableVariantType;
  13. type
  14.   TMyObjType = class(TInvokeableVariantType)
  15.     procedure Clear(var V: TVarData); override;
  16.     procedure Copy(var aDst: TVarData; const aSrc: TVarData; const Indir: Boolean); override;
  17.     function GetProperty(var aDst: TVarData; const aData: TVarData; const aName: string): Boolean; override;
  18.   end;
  19.  
  20. function NewMyObj: Variant;
  21. begin
  22.   Result := Unassigned;
  23.   TVarData(Result).VType := MyObjType.VarType;
  24. end;
  25.  
  26. procedure TMyObjType.Clear(var V: TVarData);
  27. begin
  28.   V.VType := varEmpty;
  29. end;
  30.  
  31. procedure TMyObjType.Copy(var aDst: TVarData; const aSrc: TVarData; const Indir: Boolean);
  32. begin
  33.   VarClear(Variant(aDst));
  34.   aDst := aSrc;
  35. end;
  36.  
  37. function TMyObjType.GetProperty(var aDst: TVarData; const aData: TVarData; const aName: string): Boolean;
  38. begin
  39.   Result := True;
  40.   case LowerCase(aName) of
  41.     'bark':   Variant(aDst) := 'WOF WOF!';
  42.     'moo':    Variant(aDst) := 'Mooo!';
  43.   else
  44.     Variant(aDst) := Format('Sorry, what is "%s"?', [aName]);
  45.   end;
  46. end;
  47.  
  48. initialization
  49.   MyObjType := TMyObjType.Create;
  50. finalization
  51.   MyObjType.Free;
  52. end.
  53.  

main program:
Code: Pascal  [Select][+][-]
  1. program respond2unknown;
  2. {$mode objfpc}{$h+}
  3. uses
  4.   my_obj;
  5.  
  6. var
  7.   MyObj: Variant;
  8.  
  9. begin
  10.   MyObj := NewMyObj;
  11.   WriteLn(MyObj.Bark);
  12.   WriteLn(MyObj.Moo);
  13.   WriteLn(MyObj.Meow);
  14.   ReadLn;
  15. end.
  16.  

it prints:
Code: Text  [Select][+][-]
  1. WOF WOF!
  2. Mooo!
  3. Sorry, what is "Meow"?
  4.  

Could this be submitted as a solution? Interested in any of your opinions.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11445
  • FPC developer.
Re: Rosetta Code task
« Reply #1 on: October 11, 2022, 06:46:30 pm »
IDispatch is another possible solution.

lainz

  • Hero Member
  • *****
  • Posts: 4468
    • https://lainz.github.io/
Re: Rosetta Code task
« Reply #2 on: October 12, 2022, 01:50:47 am »
IDispatch is another possible solution.

Code?

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Rosetta Code task
« Reply #3 on: October 12, 2022, 05:55:10 am »
IDispatch is another possible solution.

Thank you. I always thought IDispatch was inextricably linked to Windows and COM/OLE, didn't it?

PascalDragon

  • Hero Member
  • *****
  • Posts: 5462
  • Compiler Developer
Re: Rosetta Code task
« Reply #4 on: October 12, 2022, 07:25:16 am »
IDispatch is another possible solution.

Thank you. I always thought IDispatch was inextricably linked to Windows and COM/OLE, didn't it?

While it comes from COM/OLE there isn't anything in IDispatch itself that is platform specific however you'd need to implement the functions provided by the ComObj unit on Windows that are assigned to Variants.VarDispProc and System.DispCallByIDProc function pointers as we don't have a cross platform solution for them.

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Rosetta Code task
« Reply #5 on: October 12, 2022, 07:38:59 am »
Would it be easier than using custom variants? Maybe there is a solution using RTTI?

EDIT
Thank you PascalDragon. The question about RTTI is probably stupid.
« Last Edit: October 12, 2022, 01:55:12 pm by avk »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5462
  • Compiler Developer
Re: Rosetta Code task
« Reply #6 on: October 13, 2022, 07:38:22 am »
Would it be easier than using custom variants?

Considering that custom variants are cross platform and the IDispatch solution currently is not I'd say no.

Maybe there is a solution using RTTI?

With Extended RTTI you could probably do something like this, though this only works if the Extended RTTI is indeed enabled for that specific visibility section. But that functionality has not been integrated yet.

But in general - having looked at the Rosetta Code task - I think that this isn't something that Object Pascal can really do in the spirit of which the task was given.

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Rosetta Code task
« Reply #7 on: October 13, 2022, 08:10:06 am »
Thank you very much.

 

TinyPortal © 2005-2018