Delphi: breaking record parameter down into fields
Asked Answered
B

2

8

I have a record type

tLine = record
  X, Y, Count : integer;
  V : boolean;
end;

I have a

function fRotate(zLine: tLine; zAngle: double): tLine;

I want to pass zLine, but with its Y field reduced by 1. Is there a way to break a record down into its specific fields in a procedure or function? I tried

NewLine:=fRotate((zLine.X, zLine.Y-1, zLine.Count, zLine.V), zAngle);

which does not work. Or do I have to do as follows:

dec(zLine.Y);
NewLine:=fRotate(zLine, zAngle);
inc(zLine.Y);

TIA

Bussard answered 24/8, 2017 at 13:22 Comment(0)
I
9

You would typically make a function for this. In modern Delphi with enhanced records, I like to use a static class function like this:

type
  TLine = record
  public
    X: Integer;
    Y: Integer;
    Count: Integer;
    V: Boolean;
  public
    class function New(X, Y, Count: Integer; V: Boolean): TLine; static;
  end;

class function TLine.New(X, Y, Count: Integer; V: Boolean): TLine;
begin
  Result.X := X;
  Result.Y := Y;
  Result.Count := Count;
  Result.V := V;
end;

Then your function call becomes:

NewLine := fRotate(TLine.New(zLine.X, zLine.Y-1, zLine.Count, zLine.V), zAngle);

In older versions of Delphi you'd have to use a function at global scope.

Indignant answered 24/8, 2017 at 13:27 Comment(0)
A
3

For readability I like to use an alternative solution with record operators, like this: Note that this is updated in line with Kobik's suggestion

  tLine = record
    X, Y, Count : integer;
    V : boolean;
    class operator Subtract( a : tLine; b : TPoint ) : tLine;
  end;

class operator tLine.Subtract(a: tLine; b : TPoint): tLine;
begin
  Result.X := a.X - b.X;
  Result.Y := a.Y - b.Y;
  Result.Count := a.Count;
  Result.V := a.V;
end;

This allows this type of construct:

  fRotate( fLine - Point(0,1), fAngle );

which I think makes sense. You could obviously use a simple integer rather than an array if all you ever wanted to do was decrement Y, but this allows X and/or Y to be decremented at once.

Ambulacrum answered 24/8, 2017 at 14:29 Comment(3)
Maybe use a TPoint instead of the array. e.g. fRotate(fLine - Point(0, 1), fAngle)Iberia
Hi @Iberia I thought of that first but I wasn't familiar with the Point function, so yes, your solution is much better. I will update my answer accordingly.Ambulacrum
Thanks to both of you. I was mainly interested in knowing whether a record parameter can be broken down into its component fields; apparently not, and this is useful knowledge. It saves me the effort of searching high and low for something that is not there.Bussard

© 2022 - 2024 — McMap. All rights reserved.