1
votes

I have this code:

type
 TSolution = record
  x1, x2, i1, i2: double;
 end;

 TSupport = record helper for TSolution 
  function toFraction: string;
 end;

And I would like to be able to call something like this inside (for example) a button click event:

var k: TSolution;
begin

 //...
 Memo1.Lines.Add(k.x1.toFraction);
 //...

end;

Where toFraction is a function I have written that converts a double into a fraction. I think that a record helper is what I need but why doesn't this work?

{ TSupport }

function TSupport.toFraction: string;
begin
 Result := TFunction.DoubleToFraction(self);
end;

If you are wondering, TFunction is a class (in the same unit as the record/record helper) and it has the DoubleToFraction class function which returns a string of course.

E2010 Incompatible types: 'Double' and 'TSolution'

Ok this is the error but if I don't use the self then how can I take the parameter? The parameter would be x1, x2, i1 or i2 depending on what I need. In the example above, inside Memo1 I should convert x1 (parameter) to fraction. What to do here?


I have noticed that if you write for example

TSupport = record helper for double

Then the Self works! Basically I would like to know how to avoid the Self to refer to the TSolution record but to its double fields.

1
But why do you need helper for your own type? Why not add function/property into TSolution? - MBo
@MBo Because I already have a class function with the toFraction. I wanted to be able to add to my TSolution something "quick" like k.x1.toFraction instead of k.toFraction(k.x1) - Raffaele Rossi
That misses the point completely. Add a method to TSolution that calls your class function. Using helpers here is a complete abuse of the feature. - David Heffernan

1 Answers

3
votes

Here is the wrong context: you call

k.x1.toFraction

that means that you call a function toFraction that corresponds to x1, but it is a double, not TSolution.

Your helper function will be called form something like

k.toFraction

I assume that toFraction knows in advance which of the variables x1, x2, i1, i2: double; to take. Otherwise you can write a helper for double.

APENDED on @Remy Lebeau consideration

You can use a construction like this:

TMyDouble = record
  private
    class var FX: double;
  public
    class property X: double read FX write FX;
    class operator Implicit(a: TMyDouble): double;
    class operator Implicit(a: double): TMyDouble;
    function toFraction: string;
  end;

function TMyDouble.toFraction: string;
begin
  result := FloatToStr(self.FX { .Fraction } ); // or other FX.methods
end;

class operator TMyDouble.Implicit(a: TMyDouble): double;
begin
  result := FX
end;

class operator TMyDouble.Implicit(a: double): TMyDouble;
begin
  result.FX := a;
end;

It will emulate double functionality and seem a double being a record.