Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi 2009 Handling of With

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!

like image 387
user122603 Avatar asked Jul 15 '09 07:07

user122603


5 Answers

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.

like image 195
Rob Kennedy Avatar answered Oct 22 '22 12:10

Rob Kennedy


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**.

like image 23
Lasse V. Karlsen Avatar answered Oct 22 '22 12:10

Lasse V. Karlsen


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").

like image 28
Vinay Sajip Avatar answered Oct 22 '22 10:10

Vinay Sajip


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.

like image 3
Marco van de Voort Avatar answered Oct 22 '22 12:10

Marco van de Voort


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.

like image 1
Fabricio Araujo Avatar answered Oct 22 '22 11:10

Fabricio Araujo