Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass record parameter without declaring it first as a variable

If I am trying to call a procedure which has a record type (not object) as a parameter, is it possible to somehow pass details of that parameter "inline" without having to declare a variable of that type first?

eg assume I have this simple record type:

type TMyRecord = record   AString: string;   AnInt: Integer; end; 

and this procedure declaration:

procedure MyProcedure(Rec: TMyRecord); 

If I want to call MyProcedure do I have to declare a variable of type TMyRecord or can I do something like:

MyProcedure(TMyRecord("Test", 10)); 

That doesn't work (XE2) (get a compiler error about it expecting a ")").

So, can I do something like that? Or not possible.

Thanks

like image 628
Jason Avatar asked Jan 15 '12 07:01

Jason


2 Answers

It is possible using the advanced record structure.

For more information about advanced records, see the Records (advanced) section in Delphi help.

This is a small prototype to see how it works in your case to preinitialize a record in a function/procedure call :

Type   TRecord = record    AString : String;    AnInt : Integer;    Constructor Create( Const s : String; i : Integer);   end;  constructor TRecord.Create(const s: String; i: Integer); begin   AString := s;   AnInt := i; end;  procedure DoSomething( theRec : TRecord); begin   WriteLn(theRec.AString, ' ',theRec.AnInt); end;  begin   DoSomeThing( TRecord.Create('S',1));   ReadLn; end. 

Looking at the Delphi RTL, see the definitions of the record types TPoint and TRect in unit system.types (XE2). They define some overloaded Create constructors, which are used in lots of places to preinitialize the record structures in function/procedure calls.

like image 88
LU RD Avatar answered Sep 28 '22 10:09

LU RD


The question you are asking relates to code readability and there is a solution that avoids having to create a variable. The VCL uses this solution with the records TPoint and TRect.

Consider the definition of TPoint:

type   TPoint = record     X,Y integer   end; 

To pass a TPoint to a procedure you might do:

var   MyPoint : TPoint;  begin   MyPoint.X := 5;   MyPoint.Y := 7;   DoSomething( MyPoint ); end; 

This is fine but takes 3 lines when one is also possible using the factory function Point:

begin   DoSomething( Point(5,7) ); end; 

In Delphi, a function has been declared as follows:

function Point( X, Y : integer ) : TPoint; begin   Result.X := X;   Result.Y := Y; end; 

You can then call this function 'inline' to create the record 'on the fly' to to quickly You will see the same has been provided for TRect etc. I often put such a factory function together with the record declaration as follows, even if I don't plan to use them yet:

type   TMyRecord = record     A : integer;     B : string;   end;  function MyRecord( A : integer; const B : string ) : TMyRecord; begin   Result.A := A;   Result.B := B; end; 

Use of this technique can improved the readability of code and also ensures that you don't accidently omit setting a record element.

like image 27
Brian Frost Avatar answered Sep 28 '22 08:09

Brian Frost