Unités
Une unité est une forme de module de code ou bibliothèque regroupant des types (notamment les classes), des constantes, des variables et des routines (fonctions et procédures), qui peuvent être référencées ultérieurement au travers des directives uses pour les rendre disponibles dans un autre contexte.
Contrairement aux inclusions les unités ne dupliquent pas le code, mais permettent la réutilisation d'un ensemble de code depuis différents contextes.
Qubes inclut de nombreuses bibliothèques standards interagissant avec les structures de données Qubes ou offrant des services divers. Les unités permettent d'étendre ces bibliothèques avec du code spécifique.
Les unités peuvent être soit structurées, soit consolidées.
Unités Structurées
Les unités structurées suivent la syntaxe du Pascal traditionnel. On distingue plusieurs sections, donc certaines optionnelles:
interface
// interface des types, des routines, des variables et constantes publiques
implementation
// implémentation des méthodes, des routines, variables et constantes privées
initialization
// code d'initialisation optionnel
finalization
// code de finalisation optionnel
end.
En-tête d'unité
Elle est composée de unit suivi d'un identificateur valide (pouvant contenir éventuellement des '.') puis d'un point-virgule. Cette identificateur doit correspondre au nom du document ou du composant bibliothèque.
A partir de Qubes 6.1 on peut adjoindre une clause deprecated suivie d'un message optionnel (chaîne) afin d'indiquer qu'une unité est obsolète et que son usage est déconseillé. Il est de bon usage de préciser dans le message pourquoi l'unité est obsolète, ou par quelle(s) autre(s) unités elle a été remplacée.
Section interface
Elle débute par le mot-clef interface et se termine par le mot-clef implementation.
C'est dans cette section que sont déclarés les types, routines, variables et constantes publiques, qui seront accessibles quand l'unité sera utilisée dans d'autres contextes (via uses).
Cette section peut inclure une ou plusieurs directives uses afin d'importer types et constantes depuis d'autres unités.
Section implementation
Elle débute par le mot-clef implementation et se termine sur initialization, finalization ou end.
C'est dans cette section que doivent être placées les implémentations des routines. Il est aussi possible de déclarer des types, des variables et des constantes privées, qui ne seront pas visibles depuis d'autres contextes.
Cette section peut inclure une ou plusieurs directives uses afin d'importer types et constantes depuis d'autres unités.
Section initialization
Cette section optionnelle est destinée à recevoir du code d'initialisation pour l'unité. Elle sera exécutée avant que le code principal le soit.
Les sections d'initialisation sont initialisées dans l'ordre d'apparition des dépendances. En cas de dépendances circulaires, l'ordre n'est pas défini.
Section finalization
Cette section optionnelle est destinée à recevoir du code de finalisation pour l'unité. Elle sera exécutée après que le code principal se soit achevé.
Les sections de finalisation sont exécutées dans l'ordre inverse de celui des sections d'initialisation.
L'exécution d'une section de finalisation n'est pas garantie (en cas de crash), elle ne doit pas servir à remplacer des structures try..finally.
Unités Consolidées
Les unités consolidées fusionnent les sections interface et implementation, et sont destinées aux cas simples pour lesquels une distinction interface/implementation n'est pas nécessaire. Elles sont obtenues en déclarant directement types, routines, etc. à la suite du unit, sans inclure de mot-clef interface.
Dans une unité consolidée, les méthodes peuvent être directement implémentées suites à leur déclaration dans une classe par exemple.
Les unités consolidées ne supportent pas les types, routines, variables ou constantes privées rattachées à l'unité. Il est toutefois possible d'avoir des membres privés pour les class et les record.
Unités d'espace de nom
Supportées à partir de Qubes 6.1, elle permettent d'agréger plusieurs unités dans un même espace de nom.
uses Unit1, Unit2...;
Dans l'exemple ci-dessus un "uses UnitName" sera équivalent à un "uses Unit1, Unit2...".