[ada-france] [GNAT GPL 2007] Compilation d'un example objet du manuel Ada 2005.
Pascal
sur.pignard at wanadoo.fr
Jeu 9 Aou 18:19:32 CEST 2007
Merci Laurent pour tes patientes explications. Venant d'Ada 83, j'ai
sauté la case Ada 95.
J'essaye de défricher le terrain par moi même et de le retranscrire
(http://blady.perso.orange.fr/a_savoir.html#poo)
Bon, bon, relire le manuel :
<3.2.3 Classification of Operations
2
The primitive subprograms of a specific type are defined as follows:
3
The predefined operators of the type (see 4.5);
4
For a derived type, the inherited (see 3.4) user-defined subprograms;
5
For an enumeration type, the enumeration literals (which are
considered parameterless functions — see 3.5.1);
6
For a specific type declared immediately within a
package_specification, any subprograms (in addition to the
enumeration literals) that are explicitly declared immediately within
the same package_specification and that operate on the type;
7/2
For a nonformal type, any subprograms not covered above that are
explicitly declared immediately within the same declarative region as
the type and that override (see 8.3) other implicitly declared
primitive subprograms of the type. >
L'alinéa 6 a l'air clair. En fait, j'avais bien commencé par là,
suivant les principes de "classe-package" plus "naturels", je te
l'accorde.
Je dois expliquer pourquoi j'ai cherché alors à fait "exploser" le
package.
Je traduis des sources de Pascal en Ada avec l'incontournable
utilitaire P2Ada (http://blady.perso.orange.fr/a_savoir.html#p2ada)
J'en viens au Pascal Objet (notamment le Mac Pascal) qui n'a pas la
contrainte ci-dessus.
La traduction automatique en est forcément compliquée.
Simple question : Quelle est la raison racine de ne pas permettre
qu'Init puisse être une primitive du type Point dans ma version de
basic_obj2 ?
Est-ce la même raison de sécurité de l'exemple de J. Barnes ?
http://www.adaic.org/standards/05rat/html/Rat-2-5.html
Mais alors deux remarques :
- le source de J. Barnes compilait et de provoquait qu'une erreur à
l'exécution alors que le mien ne compile pas et ne provoquera pas
d'erreur d'exécution (j'espère ;-)
- un élargissement à la déclaration de primitives dans un sous-
programme pour un type interne au sous-programme ou dérivé d'un type
interne au sous-programme ne m'apparaît pas enfreindre la règle de
sécurité
Cordialement, Pascal.
http://blady.perso.orange.fr
Le 8 août 07 à 20:37, Laurent GUERBY a écrit :
> 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