Recent

Author Topic: write, writeln user defined type  (Read 1649 times)

jollytall

  • Full Member
  • ***
  • Posts: 158
write, writeln user defined type
« on: November 17, 2021, 01:16:04 pm »
Is there a way to use a user defined type in write(ln) through some operator overload or tweak on write?
E.g.:
Code: Pascal  [Select][+][-]
  1. type
  2.   tName = record
  3.     FirstName : string;
  4.     LastName : string;
  5.     end;
  6. operator := (Name : tName) : string;
  7.   begin
  8.   result := Name.FirstName + ' ' + Name.LastName;
  9.   end;
  10.  
  11. var
  12.   MyName : tName;
  13.   s : string;
  14. begin
  15. MyName.FirstName := 'John';
  16. MyName.LastName := 'Smith';
  17. s := MyName;
  18. writeln(s); // this works
  19. writeln(string(MyName)); // this one also works
  20. // writeln(MyName); // but I would like this
  21. end.

Kays

  • Sr. Member
  • ****
  • Posts: 398
  • Whasup!?
    • KaiBurghardt.de
Re: write, writeLn user defined type
« Reply #1 on: November 17, 2021, 02:06:25 pm »
Is there a way to use a user defined type in write(ln) through some operator overload or tweak on write?
No. The PXSC, Pascal eXtensions for Scientific Computing, allow “overloading” the standard procedures write/writeLn for custom data types, but the FPC does not provide a facility for that. Use the forum search to find more details, e.g. Is there any way to make custom Write procedure?.
Yours Sincerely
Kai Burghardt

wp

  • Hero Member
  • *****
  • Posts: 9164
Re: write, writeln user defined type
« Reply #2 on: November 17, 2021, 02:44:23 pm »
Is there a way to use a user defined type in write(ln) through some operator overload or tweak on write?
E.g.:
Code: Pascal  [Select][+][-]
  1. type
  2.   tName = record
  3.     FirstName : string;
  4.     LastName : string;
  5.     end;
  6.  
Add a method to the record:
Code: Pascal  [Select][+][-]
  1. {$modeswitch advancedrecords}
  2. type
  3.   TName = record
  4.     FirstName: String;
  5.     lastName: String;
  6.     function FullName: String;
  7.   end;
  8.  
  9. function TName.FullName: String;
  10. begin
  11.   Result := FirstName + ' ' + LastName;
  12. end;
  13.  
  14. var
  15.   MyName: TName;
  16. begin
  17.   MyName.FirstName := 'John';
  18.   MyName.LastName := 'Smith';
  19.   WriteLn(MyName.FullName);
  20. end.
« Last Edit: November 17, 2021, 10:17:01 pm by wp »
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

jollytall

  • Full Member
  • ***
  • Posts: 158
Re: write, writeln user defined type
« Reply #3 on: November 17, 2021, 05:49:30 pm »
@Keys  :(

@wp
This record was only an example, actually my type is not even a record (but an array). Anyway, why would VariableName.MethodName be a better, shorter approach then string(VariableName)?

korba812

  • Full Member
  • ***
  • Posts: 229
Re: write, writeln user defined type
« Reply #4 on: November 17, 2021, 06:49:26 pm »
Because it's more logical. Overloading an operator only to convert to string for print it may cause that the compiler to not detect accidentally assigning a record to string. The method in this case is more appropriate, as in the case of type helper for integer - "SomeString := SomeInt.ToString" but not "SomeString := SomeInt".

jollytall

  • Full Member
  • ***
  • Posts: 158
Re: write, writeln user defined type
« Reply #5 on: November 17, 2021, 08:54:20 pm »
I see. Anyway, as my type is an array, I cannot add a function to it. So I stick with it, as it is.

Btw. it would be nice to have a type only for write, like tWrite and then an operator overload
Code: Pascal  [Select][+][-]
  1. operator := (a : tMyType) : tWrite;
could work without any problem caused. Write(ln) would just check if there is a := overload to tWrite and use that if exist.

korba812

  • Full Member
  • ***
  • Posts: 229
Re: write, writeln user defined type
« Reply #6 on: November 17, 2021, 09:13:27 pm »
You can use type helpers for this:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}
  4. {$modeswitch typehelpers}
  5.  
  6. type
  7.   TMyArray = array of record
  8.     FirstName : string;
  9.     LastName : string;
  10.   end;
  11.  
  12.    TMyArrayHelper = type helper for TMyArray
  13.      function ToString: String;
  14.    end;
  15.  
  16. function TMyArrayHelper.ToString: String;
  17. var
  18.   I: Integer;
  19. begin
  20.   Result := '';
  21.   for I := 0 to Pred(Length(Self)) do
  22.     Result := Result + Self[I].FirstName + ' ' + Self[I].LastName + ', ';
  23. end;
  24.  
  25. var
  26.   Arr: TMyArray;
  27.  
  28. begin
  29.   SetLength(Arr, 2);
  30.   Arr[0].FirstName := 'John';
  31.   Arr[0].LastName := 'Doe';
  32.   Arr[1].FirstName := 'Jane';
  33.   Arr[1].LastName := 'Doe';
  34.   WriteLn(Arr.ToString);
  35. end.
  36.  

jollytall

  • Full Member
  • ***
  • Posts: 158
Re: write, writeln user defined type
« Reply #7 on: November 17, 2021, 09:50:53 pm »
Thanks, indeed that is an option. Actually I already have many explicit ways built to convert tMyType to string using different formatting parameters, but I wanted to have a simple mechanism to convert to string with the default parameter more elegantly.

Following your logic, if I understand correctly, overloading the := operator would never make sense. As a basic rule the operator overload always have to have different to and from types:
Code: Pascal  [Select][+][-]
  1. operator := (a : tType1) : tType2;
This allows
Code: Pascal  [Select][+][-]
  1. VariableType2 := VariableType1;
but as I see, you want always to use
Code: Pascal  [Select][+][-]
  1. VariableType2 := VariableType1.ToType2;
and that would kill the whole concept.
Do I miss something?

MarkMLl

  • Hero Member
  • *****
  • Posts: 3672
Re: write, writeln user defined type
« Reply #8 on: November 17, 2021, 09:51:41 pm »
Notwithstanding what everybody else has said, I'd point out that Write() etc. has nonstandard syntax in that it (a) operates on an indeterminate number of parameters and (b) has an optional [:width[:precision]] specification after each.

It has traditionally been handled "magically" by compilers, and hearks back to the ALGOL era which predates systematic use of libraries.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 3646
  • Compiler Developer
Re: write, writeln user defined type
« Reply #9 on: November 18, 2021, 09:13:42 am »
Do I miss something?

With the ToType2 one the operator overload is simply not necessary.

jollytall

  • Full Member
  • ***
  • Posts: 158
Re: write, writeln user defined type
« Reply #10 on: November 18, 2021, 10:13:47 pm »
Yes, it is true, but I do not see that making a helper and a function is simpler than making an operator (what is the same as a function).
So to me the definition part is a bit easier with the operator but the usage part is much easier and cleaner.

But probably it is a question of taste and "De gustibus non est disputandum".

MarkMLl

  • Hero Member
  • *****
  • Posts: 3672
Re: write, writeln user defined type
« Reply #11 on: November 18, 2021, 11:17:18 pm »
So to me the definition part is a bit easier with the operator but the usage part is much easier and cleaner.

I thought I'd posted a few more lines yesterday evening. You need to be /very/ careful defining an := operator, since it is likely to get used both for explicit assignment and implicit type transfer (cast etc.).

At the risk of boring, a compiler I've used in the past had :> as an explicit cast and being able to separate the usages is (in retrospect) useful: a redefined := can easily go recursive.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018