BlueWings
BlueWings

Reputation: 9

Iterate over variables in Delphi

Given the declarations :

Unit MyUnit;

interface

type

  TMyFileStream= class(TFileStream);
  ...
  end;

var
  a1,a2,a3,a4,a5: integer;
  b1,b2,b3: boolean;
  c1: char;
  d1,d2,d3,d4: TDateTime;
  f1,f2,f3,f4,f5,f6,f7,f8: TMyFileStream // LineX
  ...

procedure MyProc;

implementation

procedure MyProc
begin

  // I wanna iterate over all integer (or any other type) variables here with a loop regardless of their count and identifier name

end;

Some specific type variables' count regularly changes in code - mostly increases as I add new functions. How can I reference them in a loop to take the same action on all of them ? I want to preserve the fact that when I add a new one, the code needs to be modified at only one place.

I've already thought of putting them in an (either static or dynamic) array, but this involves the modifocation of code at every location where they are referenced, which is much-much-much work that I wanna spare if it's possible by any means.

There's currently 38 variables I want to take an acton upon, the references' count is a multiple of it far above 100.

Hope I was clear enough. Thanks for any idea.

Peter

Upvotes: 0

Views: 857

Answers (3)

Disillusioned
Disillusioned

Reputation: 14832

I've already thought of putting them in an (either static or dynamic) array, but this involves the modifocation of code at every location where they are referenced, which is much-much-much work that I wanna spare if it's possible by any means.

So what! Do it!
The longer you put off fixing horrible code, the worse it will get. Also, it's not nearly as bad as you think.

E.g. Change the following:

var
  a1,a2,a3,a4,a5: integer;

to:

var
  A: array[1..5] of Integer;

Now everything that was referring to a? will fail to compile (unless you had scope conflicts, which would be a simmering pot of disaster in any case). These compilation errors can easily be fixed by changing a? to a[?].

If you simply go through a cycle of: compile --> fix --> compile --> fix --> ... You'll find you can clean up a lot faster than you think.

Upvotes: 0

Uwe Raabe
Uwe Raabe

Reputation: 47704

Although the design smells, this is what pointers are made for:

type
  PMyFileStream = ^TMyFileStream;
  TMyFileStream= class(TFileStream)
  end;

var
  a1,a2,a3,a4,a5: integer;
  b1,b2,b3: boolean;
  c1: char;
  d1,d2,d3,d4: TDateTime;
  f1,f2,f3,f4,f5,f6,f7,f8: TMyFileStream; // LineX

function GetVarsInt: TArray<PInteger>;
begin
  result := TArray<PInteger>.Create(@a1, @a2, @a3, @a4, @a5);
end;

function GetVarsBool: TArray<PBoolean>;
begin
  result := TArray<PBoolean>.Create(@b1, @b2, @b3);
end;

function GetVarsChar: TArray<PChar>;
begin
  result := TArray<PChar>.Create(@c1);
end;

function GetVarsDateTime: TArray<PDateTime>;
begin
  result := TArray<PDateTime>.Create(@d1, @d2, @d3, @d4);
end;

function GetVarsMyFileStream: TArray<PMyFileStream>;
begin
  result := TArray<PMyFileStream>.Create(@f1, @f2, @f3, @f4, @f5, @f6, @f7, @f8);
end;

procedure HandleInt(var Value: Integer);
begin

end;

procedure HandleBool(var Value: Boolean);
begin

end;

procedure HandleChar(var Value: Char);
begin

end;

procedure HandleDateTime(var Value: TDateTime);
begin

end;

procedure HandleMyFileStream(var Value: TMyFileStream);
begin

end;

procedure MyProc;
var
  vInt: PInteger;
  vBool: PBoolean;
  vChar: PChar;
  vDateTime: PDateTime;
  vMyFileStream: PMyFileStream;
begin
  for vInt in GetVarsInt do
    HandleInt(vInt^);
  for vBool in GetVarsBool do
    HandleBool(vBool^);
  for vChar in GetVarsChar do
    HandleChar(vChar^);
  for vDateTime in GetVarsDateTime do
    HandleDateTime(vDateTime^);
  for vMyFileStream in GetVarsMyFileStream do
    HandleMyFileStream(vMyFileStream^);
end;

In case of the TMyFileStream variables, you might get away with no pointers when you only want to manipulate the existing object instances.

Upvotes: 5

Birger
Birger

Reputation: 4353

If you put these variables in a class you can use RTTI to loop over the properties of that class. There is no method that I know of to loop over variables that do not belong to a class.

Upvotes: 2

Related Questions