- 1 - L'environnement de développement
- 2 - Premier programme
- 3 - Les variables
- 4 - Les structures de contrôle
- 5 - Les attributs, les énumerations
- 6 - Les tableaux
- 7 - Les sous-programmes
- 8 - Les types
- 9 - Les packages
- 10 - Le multi-tache
- 11 - Ecrire un programme pour le robot
- 12 - Utilisation de la lib PNG_Interface
- 13 - Exercice : SimpleForth
- 14 - Exercice : Startup_Manager
- 15 - Exercice : Gestion des déplacements
Pour organiser nos programmes, on peut regrouper différentes fonctions dans un package come Les packagesUn package se compose de 2 partie :
Attention: un package nommé "toto" doit être dans les fichiers "toto.ads" et "toto.adb" La spécificationLa spécification d'un package est la liste des fonctions/procédure/types/... que ce package veux faire connaitre au reste du monde. La syntaxe est la suivante: package Package_Name is procedure Une_Procedure; end Package_Name; Le corpsLe corps du package est son implémentation. Il faut au minimum implémenter les fonctions déclarées dans la spécification. On peut rajouter des fonctions qui ne seront visibles que par les autres fonctions du package, pas par les utilisateurs. La syntaxe est la suivante : package body Package_Name is procedure Une_Procedure is begin null; end Une_Procedure; end Package_Name; La partie privateUn package peut contenir une partie private : package Package_Name is procedure Une_Procedure; private procdure Une_Procedure_Private; end Package_Name; Cette partie "private" peut contenir un peu tout et n'importe quoi. Ce qui y sera définit n'est visible que par les membres du package et de ses sous-packages (cf. plus loin). Mais surtout, grâce à cette partie "private", on peut définir des types "private". Exemple : on veut faire un package "Stack", avec 2 méthodes "Push" et "Pop" et un type : "Stack_Type". Ce type va être un record avec un tableau et un pointeur sur le 1er élément de la pile. Idéalement, les utilisateurs du package ne devrait pas savoir ce qu'il y a dans ce type, comme ça on est sur qu'ils ne le modifieront pas, et si jamais on change de façon de faire (avec par exemple une allocation dynamique de la mémoire) on est sur que tout marchera encore. Pour faire cela, on va déclarer notre type "private": package Stack is type Stack_Type is private; procedure Push (Stack : in out Stack_Type; Value : Integer); procedure Pop (Stack : in out Stack_Type; Value : out Integer); private Max_Size : constant Integer := 100; type Buffer_Type is array (1 .. Max_Size) of Integer; type Stack_Type is record Buffer : Buffer_Type; Top : Integer := 0; end record; end Stack; Un utilisateur pourra déclarer un élément de type Stack.Stack_Type mais ne pourra pas savoir ce que cette élément contient. InitialisationUn package peut aussi comporter une partie d'initialisation. La syntaxe est très simple: package body Package_Name is procedure Une_Procedure is begin ... end Une_Procedure; ... begin Code_D_Initialisation; end Package_Name; Le code entre le Ordre d'élaborationL'élaboration d'un programme consiste à initialiser ses variables et exécuter son éventuelle partie d'initialisation. L'ordre d'élaboration peut poser un problème puisque les parties d'initialisation peuvent appeler des procédures : il faut être sur que toute les variables utilisé par ces procédures sont initialisé. Une règle simple aurait pu être d'élaborer un package dès que quelqu'un en fait un "with" mais cela empêcherait les packages qui se "with" l'un l'autre : lequel initialiser en premier ? Ada utilise des règles pour définir un ordre d'élaboration intelligeant. Généralement, ca se passe bien. Pour influer sur l'ordre d'élaboration, on peut utiliser quelque pragma : pragma Elaborate_AllLe plus courant : lorsque le compilateur se rend compte qu'on utilise une fonction qui risque de ne pas être élaborée, on reçoit un message de ce type : >>> warning: call to "Set_X" may raise Program_Error pragma Elaborate_BodyNormalement, un programme est une procédure. Il arrive qu'il soit plus simple d'utiliser un package. Dans ce cas, l'initialisation du package est le programme principale. L'ads du package est donc vide. Hors, si le compilateur voir un ads vide, il ne comprend pas qu'il puisse y avoir un adb. Pour dire au compilateur que l'ads est vide et que c'est normal, on met un pragma dans l'ads, par exemple : package Simulator is pragma Elaborate_Body; end Simulator; Pour aller plus loinPour plus d'info, voir par exemple la :http://gnu.huihoo.org/gcc/gcc-3.3.6/gnat_ug_unx/Elaboration-Order-Handling-in-GNAT.html#Elaboration-Order-Handling-in-GNAT Sous-packageUn package peut avoir des packages enfants. Cela permet d'organiser un peu ses packages. Par exemple, pour notre robot, tous les packages qui ce rapport à la shix sont des sous packages de Shix. Nom du packageLa hiérarchie des packages se représente en utilisant un "." pour séparer les noms de packages. Attention : dans les noms de fichiers, le "." devient un "-". Ainsi, un sous-package B d'un package A a pour nom A.B et il se trouvera dans les fichiers a-b.ads et a-b.adb. VisibilitéUn sous-package fait automatiquement un "with" de tous ses parents. En revanche, il n'est pas possible de "wither" un sous-package dans son parent. De plus, un sous-package peut accéder à la partie "private" de ses parents. Ceci permet, entre autre de mettre des choses pour le débogage/test dans la partie private d'un package. Les utilisateurs standards n'y auront donc pas accès alors que les programmes de tests feront un "with" d'un sous-package qui aura lui accès à ses fonctions et pourra même éventuellement les exporter.
|
|||




