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

Jürgen Hestermann juergen.hestermann at gmx.de
Tue Aug 2 18:39:23 CEST 2011


Max Vlasov schrieb:
 > Personally I stopped using 'with' keyword long time ago, but there 
are code fragments from the past and today I fixed a little bug showing 
again that it's a evil.
 > TCanvas in lazarus has width and height properties while in Delphi it 
hasn't (at least some time ago). So the code below leads to different 
results in lazarus and Delphi, at least for design-time drawing.
 > procedure TControlDescendant.Paint;
 > begin
 >   with Canvas do
 >   begin
 >       Rectangle(0, 0, Width, Height);
 >   edn;
 > end;
 > So not only the 'with' context can silently change while the project 
is evolving, it can also change while it's being ported...


I don't know what "Width" and "Height" refer to in Delphi if Canvas has 
no such properties. In general I would expect to get an "unknown 
identifier" error message in this case. I think that the possibility of 
correct syntax (but different behaviour) is not very high. But of 
course, porting code is always an adventure.


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;
-----------------------------------------------------------------------

It also saves you from typos within some of the expressions because you 
only have to type them once. Identifiers have to be unique to make it 
work but I never had a problem with a with statement so far.







More information about the Lazarus mailing list