A Delphi "Unit" is basically the same thing as a "Namespace". In other languages such as C#, a namespace can be declared in many different units (files). But in older versions of Delphi, 1 single unit represents an entire "namespace". Newer versions of Delphi have new namespace capabilities, which I won't cover, because I don't know about these new abilities.
It was a little hard to understand exactly what you are asking, so here are the basics of structuring a unit in Delphi.
There are many different things you can put in a raw unit. It all depends on the purpose of the unit. At the very top, just under interface
, is where you begin declaring things. You can declare uses, constants, types, variables, methods, etc. The order of these sections should be in the order of the unit below (and I'm sure I'm probably missing something).
To avoid circular-referencing, you are able to declare a uses
clause beneath the implementation
section. This is only usable to the code below it, and not to the code above it. See below. You can have two units use each other (A using B and B using A) if you put your unit in the implementation section, but you can't if you put it in the interface section.
unit MyUnit;
interface
uses
{ Whatever other units you need to use }
{ These are other unit files (or namespaces) you need for your code below }
Classes, SysUtils, Windows;
const
{ Whatever constants you would like to add }
{ These are static and cannot be changed programmatically }
SOME_INT_CONST = 123;
SOME_STR_CONST = 'Some Constant';
type
{ Whatever types you would like to add }
{ These are your own types and should all be prefixed with the capital letter 'T' }
TMyObject = class(TObject)
private
FSomeField: String;
procedure SetSomeField(const Value: String);
public
property SomeField: String read FSomeField write SetSomeField;
end;
var
{ Whatever variables you would like to add }
{ This I believe is what you intend by your question }
SomeVar: String;
SomeObject: TMyObject;
{ Finally whatever global methods you would like to add }
{ These methods will be available from any other unit which uses this unit }
procedure DoSomething(SomeParam: String);
implementation
uses
{ Whatever other units you need to use }
{ This can be used in 2 units and cross-reference each other, if needed }
{ but can only be used in implementation below, not in anything above }
{ This I believe should solve your 'circular reference' issues }
MyOtherUnit;
procedure DoSomethingElse;
begin
{ This procedure isn't declared above, so it won't be available to other units }
{ Only things declared in `interface` can be accessed from other units. }
end;
procedure DoSomething(SomeParam: String);
begin
//Whatever code needed to do something with 'SomeParam'
if SomeParam = SOME_INT_CONST then begin
ShowMessage('They are the same!');
end;
end;
procedure TMyObject.SetSomeField(const Value: String);
begin
if FSomeField <> Value then begin
FSomeField:= Value;
DoSomething(Value);
end;
end;
end.
There isn't any such thing as "calling a unit" - as long as it is in your uses clause, it will automatically be included and compiled in your project. You don't call the unit, you call things in the interface of that unit.