views:

685

answers:

2

Trying to rearrange my packages for a set of TFrame-descendent components, I'm finding it seemingly necessary to break out some of my utility TFrame descendents separate from the dialog forms which use them, mainly because the former are registered to the palette as true components and that seems to confuse the IDE sometimes with respect to the dialog forms which use them. The dialog forms in turn are called by non-visual components, which are part of a third package. This, so far, seems to make most of the compiler's dependency-related complaints / confusions go away. (I'm not out yet, however).

When compiling the package with the dialog forms (which call the Frames), I am getting the warning "Unit 'MyFrames' implicitly imported into package 'MyDialogForms'"

Given that it shows up as a compiler warning, I've long ago gotten the impression that "implicitly importing" a unit is generally not a good thing. Are there specific instances where that is not the case? i.e. where implicitly importing a unit is OK, and/or an appropriate practice?... and if so, what are those specific cases?

+14  A: 

Here's the issue:

You can only have one copy of a unit in your program. If you try to load the same unit twice via packages, it will raise an exception and the package won't load the second time. The way to avoid this is to structure your packages so that no unit is used in more than one of them.

The code to every unit you compile has to be in the package. The compiler will start with all the units you declare in the contains section, but any other units used by those units also has to be compiled in so it will be reachable, unless those units are contained in another package which is listed under requires. These extras are the "implicitly imported" units. Trouble is, they're imported implicitly, not explicitly stated in the contains section where they'll conveniently show up in the Project Manager off to the right. This means that you might not notice that your unit is in a package, and end up putting it in another one. Then when you try to run your program and load the packages, things break. That's why the compiler warns you about it.

It's a warning, and not an error, for a reason. As long as you understand how the system works, it's technically safe to use implicit imports. Just remember that those units are ending up in the package whether you declare them or not. But then again, since they're ending up there whether you declare them or not, it's probably simpler just to officially add them and save yourself the hassle.

Mason Wheeler
(note that in the package doesn't mean in the BPL. See $weakpackageunit;)
Marco van de Voort
Mason - THANK YOU! This is the most cogent, succinct conceptual overview I've read on this since my package sagas began.
Jamo
How does Delphi handle the recurring references to fundamental units like SysUtils, Forms, etc. across packages? It seems like these would cause the same kind of problem.
Jamo
By putting them in their own packages (such as "vcl" and "rtl") and then your package **requires** them.
Mason Wheeler
K - that makes sense. I'm still running around in circles with inscrutable errors galore (just now the "Error opening ____.drf" issue again), but your explanation here is very helpful. Thanks again.
Jamo
If you really like my answer, please mark it as accepted. :)
Mason Wheeler
Maon, I *finally* got this problem solved, thanks mostly to your opening phrase "You can only have one copy of a unit in your program," diagramming my class/unit/package relationships, and ferreting out all "implicitly imported" warning. THANK YOU for your advice and conceptual explanations here. I have definitely marked you answer as "accepted" now. : ) Thanks again!
Jamo
Glad to be of help. Did it take you this long, or did you leave the problem and come back to it?
Mason Wheeler
+4  A: 

+1 for Mason's answer. The place where implicitly-imported units become a problem is on a large project where it becomes exponentially more difficult to keep track of units that are linked in from whereever.

I find the best way by far is to have a folder per package, and that folder contains all the files for the package. If I see an "implicit import" warning, I either add the required package, or add the unit to the package. So all units are specified in the package that contains them and they are all in the same folder. I never add folders to the Search Path, because every project knows about all its files directly.

The structure is really not terribly difficult to maintain and it protects you from problems where different units contain different versions of a file.

Cobus Kruger
This sounds like a solid recommendation -- I may try it out! Thanks for the reply, Cobus. Much appreciated.
Jamo