[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