I hate to even talk about it, but it’s not difficult to understand how the rules of the region work. The last victory. Is always.
But people have this problem, which in psychology is called Chunk Theory. When you are offered seven things that you need to track in your mind, one drops out because your brain has about 6 local registers to hold things. Imagine a simple Foo id:
with EXPRESSION1 do begin with EXPRESSION2 do begin Foo; end; end;
The above for all intentions is identical with EXPRESSION1, EXPRESSION2 do begin...
So, let's see how simple rules, such as a domain, become too complex to follow after a while. Imagine that in some delphi applications we work in the following areas:
- The unit of measure that is in your
use clauses. - Your own block implementation area (Internal Elements)
- Class (identifiers inside your current class if you write a method)
- Local area of procedures or methods (var section in a procedure or function).
- The first with the statement in the example above.
- The second with the expression in the example above.
Update David pointed out to me that I should mention that instead of the 6 "areas" above, we really have 5 + x areas, where x is the length of both uses clauses.
Now the problem is not that the WITH statement is unclear, it is that people can easily get lost when you have 6 layers of lexical coverage, as mentioned above, and requires that you not only know about all the places where Foo is defined, because if you think that the internal With statement has something called Foo , and you are not getting pretty nasty and hard to find an error in your code. So, we have very smart, very capable people, such as Nick, saying very reasonable things like "never use." And I agree 99% with Nick.
I also think that you could say that the adversary is not with this, Delphi developers tend to just continue to grow their applications iteratively in the RAD style until they become monsters. A unit that uses 200 other units is a mess, each of which uses 200 other units, will lead to even greater grief, even than the rampant abuse of WITH statements.
WITH is not the whole problem in bad code, it is simply the most common bee in the hood of a Delphi developer. Maybe it attracts more attention than overly large offers, but throughout my career, addictions - hell and huge uses - things have done 100 times more to make life harder than WITH . Therefore, I believe that WITH considered harmful recycled, and other things that should be considered more are being considered.
A reasonable alternative to using c is to use a variable name with a single letter (I know, agree and disagree) and avoid any ambiguity:
procedure NoWithPlease; var a:TSomething; begin a := Some.Long.Expression[x].That.You.Dont.Want.To.Repeat.Six.Times; a.Foo := 'test'; a.Bar := 'test2' end;
This is better, many will say than this:
procedure WithPleasure; begin with Some.Long.Expression[x].That.You.Dont.Want.To.Repeat.Six.Times do begin Foo := 'test'; Bar := 'test2' end; end;
Now I have been bitten WITH too much to defend its unlimited use. But I also think that there are times when this is actually better than using local variables. This does not require you to declare a local variable or define the type of expression. If delphi has a type inference (the auto keyword in C ++), then I would say that we could easily do without WITH completely, but be that as it may, this is a kind of way to avoid the static creation of implementation-dependent types, and also the ability to create readable sub-areas, sometimes it can make your code easier to read, and sometimes make it worse, especially when there is more than one level of WITH statements.
However, opinions on this issue are changing, and, like other programming topics, they tend to turn into a discussion on a bike scam or, even worse, a holy war.
My suggested rules:
Avoid WITH unless this makes your code better. In most places that you think you need, you do not use a local variable.
Always avoid multi-level WITH statements.