[Lazarus] 'with' is evil, isn't it?

Martin lazarus at mfriebe.de
Tue Aug 2 18:57:16 CEST 2011


On 02/08/2011 17:39, Jürgen Hestermann wrote:
>
> In general I find the "with" statement very useful and have used and 
> do use it a lot. Though it must be used in well defined short code 
> blocks only. If you have very convoluted data structures with deeply 
> nested arrays and records and pointers to them then it is a benefit 
> not to be forced to write the same expression over and over again. And 
> it also saves the program from calculating array indices and other 
> references in these expressions multiple times so it speeds up the 
> code too. I.e., if you have an expression like this:
>
> -----------------------------------------------------------------------
> AusdehnungInMeter := 
> (Qarray[QuaderNr]^.Teilung[R].Feldgrenzen[length(Qarray[QuaderNr]^.Teilung[R].Einteilungen)+1] 
> -
>                                     
> Qarray[QuaderNr]^.Teilung[R].Feldgrenzen[1]) *
>                                     
> EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor;
> -----------------------------------------------------------------------
>
> it is much easier to read (and calculate) in a with statement:
>
> -----------------------------------------------------------------------
> with Uebergabe^, Qarray[QuaderNr]^.Teilung[R] do
>   AusdehnungInMeter := (Feldgrenzen[length(Einteilungen)+1] -
>                                       Feldgrenzen[1]) *
>                                       
> EinheitAuswahl[Einheit.Koord[R]].Faktor;
> -----------------------------------------------------------------------
>
Why put Uebergabe^ in the with? It appears only once?


Assuming objects, better add helper methods

function TFooTeilung.GetLastFirstDiff;
begin
   Result := Feldgrenzen[ length(Einteilungen)+1 ] - Feldgrenzen[1];
end

AusdehnungInMeter :=
    Qarray[QuaderNr]^.Teilung[R].  GetLastFirstDiff
    *  EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor;


You can also introduce
    FeldgrenzenBackwards[x]
where 0 returns the last, 1 the one before last ....

If it may be other than last and first, give 2 params to    
GetLastFirstDiff(  ElemFromEndIdx,   ElemFromStartIdx  )
eg GetLastFirstDiff(0,0) for Last-First

Would further shorten this (assuming that Einteilungen and Feldgrenzen 
are of the same length ?)

IMHO, that makes it much more readable.



you can even add an appropriately named method to the object returned by 
"Qarray[QuaderNr]^" , if it is an object (or record with method)

AusdehnungInMeter :=
    Qarray[QuaderNr]^.  GetLastFirstDiffForTeilung(R)
    *  EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor;

OR
AusdehnungInMeter :=
    Qarray[QuaderNr]^.  GetLastFirstDiffForTeilungFooBar(R, Uebergabe)


and do the multiplikation inside that (you got Uebergabe and R


Martin




More information about the Lazarus mailing list