The Delphi Language, Part 2 - Scope and Units and Namespaces
(Page 3 of 14 )
Scope refers to some part of your program in which a given function or variable is visible to the compiler. A global constant is in scope at all points in your program, for example, whereas a variable local to some procedure only has scope within that procedure. Consider Listing 5.2.
Listing 5.2 An Illustration of Scope
1: program Foo;
2:
3: {$APPTYPE CONSOLE}
4:
5: const
6: SomeConstant = 100;
7:
8: var
9: SomeGlobal: Integer;
10: D: Double;
11:
12: procedure SomeProc;
13: var
14: D, LocalD: Double;
15: begin
16: LocalD := 10.0;
17: D := D - LocalD;
18: end;
19:
20: begin
21: SomeGlobal := SomeConstant;
22: D := 4.593;
23: SomeProc;
24: end.
SomeConstant, SomeGlobal, and D have global scope—their values are known to the compiler at all points within the program. Procedure SomeProc() has two variables in which the scope is local to that procedure: D and LocalD. If you try to access LocalD outside of SomeProc(), the compiler displays an unknown identifier error. If you access D within SomeProc(), you'll be referring to the local version; but if you access D outside that procedure, you'll be referring to the global version.
Units and Namespaces Units are the individual source code modules that make up a Delphi program. A unit is a place for you to group functions and procedures that can be called from your main program. To be a unit, a source module must consist of at least three parts:
- A unit statement—Every unit must have as its first noncomment, nonwhitespace line a statement saying that it's a unit and identifying the unit name. The name of the unit must always match the filename, excluding the file extension. For example, if you have a file named FooBar.pas, the statement would be
unit FooBar;
- The interface part—After the unit statement, a unit's next functional line of code should be the interface statement. Everything following this statement, up to the implementation statement, are the types, constants, variables, procedures, and functions that you want to make available to your main program and to other units. Only declarations—never routine bodies—can appear in the interface. The interface statement should be one word on one line:
interface
- The implementation part—This follows the interface part of the unit. Although the implementation part of the unit contains primarily procedures and functions, it's also where you declare any types, constants, and variables that you don't want to make available outside of this unit. The implementation part is where you must define any functions or procedures that you declared in the interface part. The implementation statement should be one word on one line:
implementation
Optionally, a unit can also include two other parts:
An initialization part—This portion of the unit, which is located near the end of the file, contains any initialization code for the unit. This code will be executed before the main program begins execution, and it executes only once.
A finalization part—This portion of the unit, which is located in between the initialization and end. of the unit, contains any cleanup code that executes when the program terminates. The finalization section was introduced to the language in Delphi 2.0. In Delphi 1.0, unit finalization was accomplished by adding a new exit procedure using the AddExitProc() function. If you're porting an application from Delphi 1.0, you should move your exit procedures into the finalization part of your units.
A unit also implies a namespace. A namespace provides a logical, hierarchical means to organize an application or library. Dot notation can be used to create nested namespaces to prevent name collisions. It's common practice to nest namespaces three levels: company.product.area; for example, Borland.Delphi.System or Borland.Vcl.Controls.
Note - When several units have initialization/ finalization code, execution of each section proceeds in the order in which the units are encountered by the compiler (the first unit in the program's uses clause, then the first unit in that unit's uses clause, and so on). Also, it's a bad idea to write initialization and finalization code that relies on such ordering because one small change to the uses clause can cause some difficult-to-find bugs!
This chapter is from Delphi for .NET Developer's Guide, by Xavier Pacheco (Sams, 2004, ISBN: 0-672-32443-1). Check it out at your favorite bookstore today.
Buy this book now. |
Next: The uses Clause and Circular Unit References >>
More .NET Articles
More By Xavier Pacheco