Recent

Author Topic: How to add an operator for an inner member of a Record?  (Read 1109 times)

jamie

  • Hero Member
  • *****
  • Posts: 6735
How to add an operator for an inner member of a Record?
« on: July 21, 2024, 03:43:05 am »
Lets say I have this

Code: Pascal  [Select][+][-]
  1. TMyReord = Record
  2.  X,Y:Double;
  3.  //...... lots of other stuff and record overloads that work.
  4. End;
  5.  

So have cases where the X, Y need to be assigned to an INTEGER, this involves using round or trunc and it gets code sloppy.

I try this.

Code: Pascal  [Select][+][-]
  1. TmyReocrd = Record
  2.  X,Y:Double;
  3. class operator := (A:TmyRecord.X):Integer;
  4. End;
  5.  

That didn't get past the sniff test on the compiler.

I would like X,Y to be able to resolve to an Integer or Double using the same named variables.
Currently I put in 2 inlined functions of Xi and Yi.

The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 16169
  • Censorship about opinions does not belong here.
Re: How to add an operator for an inner member of a Record?
« Reply #1 on: July 21, 2024, 07:16:19 am »
That does not work because the class operator needs to be explicit var.
You can do that yourself, otherwise report back, but that is the only issue: var!
If I smell bad code it usually is bad code and that includes my own code.

egsuh

  • Hero Member
  • *****
  • Posts: 1490
Re: How to add an operator for an inner member of a Record?
« Reply #2 on: July 21, 2024, 09:19:52 am »
I'm afraid I do not get your idea exactly. Using property like AsInteger, AsFloat, etc. doesn't work?

TRon

  • Hero Member
  • *****
  • Posts: 3623
Re: How to add an operator for an inner member of a Record?
« Reply #3 on: July 21, 2024, 12:01:45 pm »
Can you provide a hypothetical practical example (better yet multiple) of how you want to use that ?

The solution relies on what it is that you actually want to do in practice and depending on that the implementation might differ considerably (if at all possible).

e.g. I have the hunch you are looking at the wrong level and you should decent an extra one making double and integer assignment compatible with an operator.
« Last Edit: July 21, 2024, 12:14:19 pm by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Thaddy

  • Hero Member
  • *****
  • Posts: 16169
  • Censorship about opinions does not belong here.
Re: How to add an operator for an inner member of a Record?
« Reply #4 on: July 21, 2024, 04:14:09 pm »
It is not hypothetical: it needs to operate on the instance, not on the record or class type, so it needs to be var. Of course I will add a small example later. Too many old hands making too many mistakes today. (hè, 440bx)
If I smell bad code it usually is bad code and that includes my own code.

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: How to add an operator for an inner member of a Record?
« Reply #5 on: July 21, 2024, 04:49:02 pm »
I found out how to do it.

For the rest of you old cronies  :D, try this.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeSwitch AdvancedRecords}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  10.  
  11. type
  12.  
  13. { TMyInnerRecord }
  14.  
  15. TMyInnerRecord = Record
  16.   ADouble:Double;
  17.  Class operator := (A:TMyInnerRecord):Double;
  18.  Class Operator := (A:Double):TmyInnerRecord;
  19.  Class operator := (A:TMyInnerRecord):Integer;
  20. end;
  21.  
  22. { TMyRecord }
  23.  
  24. TMyRecord = record
  25.    X,Y:TMyInnerRecord;
  26.  
  27.    //Whole bunch of other stuff in it.
  28. end;
  29.  
  30.   { TForm1 }
  31.  
  32.   TForm1 = class(TForm)
  33.     Button1: TButton;
  34.     procedure Button1Click(Sender: TObject);
  35.   private
  36.  
  37.   public
  38.  
  39.   end;
  40.  
  41. var
  42.   Form1: TForm1;
  43.   R:TMyRecord;
  44.  
  45. implementation
  46.  
  47. {$R *.lfm}
  48.  
  49. { TMyRecord }
  50.  
  51. class operator TMyInnerRecord.:=(A: TMyInnerRecord): Double;
  52. begin
  53.   Result := A.ADouble;
  54. end;
  55.  
  56. class operator TMyInnerRecord.:=(A: Double): TmyInnerRecord;
  57. begin
  58.   Result.ADouble := A;
  59. end;
  60.  
  61. class operator TMyInnerRecord.:=(A: TMyInnerRecord): Integer;
  62. begin
  63.   Result := Round(A.ADouble);
  64. end;
  65.  
  66. { TForm1 }
  67.  
  68. procedure TForm1.Button1Click(Sender: TObject);
  69. Var
  70.   X,Y:Integer;
  71. begin
  72.   R.x:= 2.6;
  73.   R.y:= 4.4;
  74.   X:= R.x; Y:= R.Y;
  75.   Caption := X.Tostring+','+y.Tostring;
  76. end;
  77.  
  78. end.
  79.  
  80.  
The only true wisdom is knowing you know nothing

TRon

  • Hero Member
  • *****
  • Posts: 3623
Re: How to add an operator for an inner member of a Record?
« Reply #6 on: July 21, 2024, 05:42:55 pm »
Why not:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$h+}
  2.  
  3. type
  4.   TMyRecord = record
  5.     x,y: Double;
  6.   end;
  7.  
  8. operator := (Src: double) dst: integer;
  9. begin
  10.   dst := Round(src);
  11. end;
  12.  
  13. var
  14.   R    : TMyRecord;
  15.   X, Y : integer;
  16. begin
  17.   R.x := 2.6;
  18.   R.y := 4.4;
  19.   X := R.x;
  20.   Y := R.y;
  21.   writeln('x = ', x);
  22.   writeln('y = ', y);
  23. end.
  24.  

You would have to add some additional suggestion for me to show what exactly you want to do the other way around.

What record operators are good for is f.e. assigning one record type to another. e.g.
Code: [Select]
Type
  TMyIntegerRec = record
   x,y: integer;
  end;
  TMyFloatRec = record
   x,y: double;
  end;

Var
  I: TMyIntegerRec;
  F: TMyFloatRec; 

...
  I := F;
...
... and then add record operators to them.

Not that there is anything wrong what you showed it just seems a bit overkill to me (but I do not fully know/understand your objective)
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: How to add an operator for an inner member of a Record?
« Reply #7 on: July 21, 2024, 07:23:04 pm »

Well, I Think Delphi does not support those kinds of operators living outside the record.

And also, I don't want everything to automatically converted to integer where some values must remain in their fractional state.

In any case, I figured I would post that because it is also a good way to have anonymous style records, so you don't need to have extra indexing into the record. This way you can generate an operator for it and keep it to a single identifier.

 In C/C++ you can have anonymous structs/Unions and gets hard to port over if you have to add extra identifiers.


The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018