[ada-france] [GNAT GPL 2007] Compilation d'un example objet du manuel Ada 2005.

Laurent GUERBY laurent at guerby.net
Mer 8 Aou 20:37:23 CEST 2007


On Wed, 2007-08-08 at 20:22 +0200, Pascal wrote:
> Merci Laurent, pour cette réponse.
> 
> Hum, j'avais bien lu (survolé plutôt) ce paragraphe, tiré de  
> l'excellent "Rationale for Ada 2005" de J. Barnes, excellent pour  
> aborder Ada 2005.
> Je comprends en effet que la dérivation (extension) d'un type objet  
> au sein d'un sous-programme peut mener à un PROGRAM_ERROR.
> 
> En fait, il n'y a pas d'interdiction d'Ada 2005 de créer et de  
> dériver des types objets au sein d'un sous-programme, exemple du  
> manuel sans erreur :
> procedure basic_obj is
> type Point is tagged
>    record
>      X, Y : Float := 0.0;
>    end record;
> type Expression is tagged null record;
>    -- Components will be added by each extension
> type Color  is (White, Red, Yellow, Green, Blue, Brown, Black);
> type Painted_Point is new Point with
>    record
>      Paint : Color := White;
>    end record;
>      -- Components X and Y are inherited
> Origin : constant Painted_Point := (X | Y => 0.0, Paint => Black);
> begin
> null;
> end basic_obj;

Tu declare seulement des types, pas des primitives ici.

> D'ailleurs, GNAT autorise même la déclaration mais pas l'utilisation:
> procedure basic_obj2 is
> type Point is tagged
>    record
>      X, Y : Float := 0.0;
>    end record;
> procedure Init (O: in out Point; X, Y : Float) is
>    begin
>    O := (X, Y);
>    end;
> procedure Deplace (O: in out Point'Class; DX, DY : Float) is
>    begin
>    O.X := O.X + DX;
>    O.Y := O.Y + DY;
>    end;
> type Color  is (White, Red, Yellow, Green, Blue, Brown, Black);
> type Painted_Point is new Point with
>    record
>      Paint : Color := White;
>    end record;
>      -- Components X and Y are inherited
> procedure Init (O: in out Painted_Point; X, Y : Float; P: Color) is
>    begin
>    Init (O, X, Y);              -- error
>    O.Paint := P;
>    end;
> Origin : constant Painted_Point := (X | Y => 0.0, Paint => Black);
> OP : Painted_Point := Origin;
> begin
> OP.Deplace (3.0, 4.0);
> end basic_obj2;

Tu ne declare pas de primitives non plus dans ce code (Init n'est pas
une primitive de Point ici), l'erreur de GNAT est tout a fait legitime. 

Ci dessous un exemple qui compile et qui declare une primitive.

De maniere generale, sauf cas tres tres particulier (l'exemple du
Rationale est l'illustration d'un de ces cas) on ne declare jamais de
types dans des procedures principales mais dans des packages.

Si tu commence dans la programmation objet en Ada 2005 (ce que je
suppose car le premier point dans la programmation object Ada 95 c'est
ou declarer une primitive vs une non primitive :), je te conseille
fortement de mettre les objets dans des package separes, tout sera bien
plus naturel.

Sincerement,

Laurent

procedure basic_obj2 is

   package Sub is
      type Point is tagged
         record
            X, Y : Float := 0.0;
         end record;
      procedure Init (O: in out Point; X, Y : Float);
   end Sub;

   package body Sub is
      procedure Init (O: in out Point; X, Y : Float)   is
      begin
         O := (X, Y);
      end;
   end Sub;

   use Sub;

   type Color  is (White, Red, Yellow, Green, Blue, Brown, Black);
   type Painted_Point is new Point with
      record
         Paint : Color := White;
      end record;
   -- Components X and Y are inherited
   procedure Init (O: in out Painted_Point; X, Y : Float; P: Color) is
   begin
      Init (O, X, Y);              -- error
      O.Paint := P;
   end;
   Origin : constant Painted_Point := (X | Y => 0.0, Paint => Black);
   OP : Painted_Point := Origin;
begin
   null;
end basic_obj2;




Plus d'informations sur la liste de diffusion Ada-France