Anybody know what is different about Delphi 2009's handling of "with"?
I fixed a problem yesterday just by deconstructing "with" to full references, as in "with Datamodule, Dataset, MainForm". Delphi 2006 and earlier applied "Close" to the Dataset. Delphi 2009 applied "Close" to the MainForm and exited the application!
Nothing has changed. Your previous observation was wrong. The objects mentioned in a with
statement are considered "right to left," so in your example, MainForm
would be searched first, then Dataset
, and then Datamodule
. That's how it's always been. It's the same as if you'd written this:
with Datamodule do
with Dataset do
with MainForm do begin
Close;
end;
Go ahead and check the Delphi 2006 documentation; there should be a section named Declarations and statements, under which you'll find Structured statements, including the section on With statements.
Do yourself a favor and don't use with
. It causes no end of trouble both during debugging and during maintenance, where maintenance could even be performed by the person who wrote the code just the day before.
With
is evil. I don't know how many times I need to say this, but apparently we're not there yet.
With can only "safely" be used with objects that are never going to change. If you apply it to objects you define in your own project, all bets are off and I'd daresay you should rather just use "if Random(50)<25" parts to execute your code, it's at least documented to executed oddly.
The problem is that once you start messing with an object, introducing new methods or properties, or renaming old ones, all existing with
-statements that use those methods has the potential to change meaning. And not in the "Warning: Call to ambiguous method" change either. The code will just do something other than it did previously. Without telling you about it.
For instance, let's assume you have this:
with connection, file do
begin
Close;
end;
then what do you expect to happen? Well, it's natural to close a file, so I would expect the file to be closed. Let's further assume that this file variable holds a object of type TSomeOddFile that doesn't define a Close method, but rather a CloseFile method. The above With-statement will then close the connection instead.
All good, it's documented, nobody wrote this piece of code thinking that the file would be closed, after all, the method is named CloseFile for that object, it's just my assumption that is wrong and I don't work on the project. Yet.
And then someone fixes that, renaming CloseFile to Close. The above code will silently start closing the file instead of the connection. No warning, no error, compiles just as fine as before you changed the method name. Runs just as fine^h^h^h, no wait, it won't.
So yeah, with
will bite you in the a**.
Using with A,B,C,D
is bad practice since changes to other units can suddenly cause your code to stop working as expected. See here for more information, or here (search for "with keyword"
).
The compiler is usually quite solid, so I wouldn't assume a bug or change before you really excluded everything else. Some things I can quickly think of:
1) Look if you use overloaded functions or operators. Since the definition of STRING (and several other types) changed, a different variant can be chosen, because the signature effectively changes.
2) it can also be that some included unit now defines an identifier that is already used, and taking precedence over the one exposed in an different unit.
If not, start isolating the code in a minimal example, using as little units as possible. Do it step by step, since the trick is what the last change was when the behaviour changed.
Post that (or an URL) here, it is always interesting to see.
With..do is to be used with care. Otherwise, is a infinite source of headaches.... I agree with Rob Kennedy and others.
As Craig Stuntz (in other post about with..do) and Lasse V. Karlsen above said, with..do can create a lot of traps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With