Ada à de très beaux conteneurs¹ et le résultat est beau et puissant.
>
Ca c'est une bonne idée.
Je ne sais pas pourquoi mais j'étais focalisé sur l'utilisation des types de base du langage (array, record...).
Utiliser aussi des conteneurs (vector, map...) est sûrement la solution.
Dynamisme, souplesse, ça manque un peu d'exemples dès qu'on dépasse le conteneur qui ne contient qu'un type de base mais je peux te passer des exemples plus complexes (voir déjà un exemple d'instanciation plus bas). À priori vecteur dans ton cas.
Je fais ça parfois avec des collègues et en général c'est très efficace. Je ne savais pas que ça s'appelle "méthode du canard en plastique".
Méthodologie efficace pour tout problème qui fait face à un biais de confirmation (la personne a la solution devant son nez mais ne la voit pas car elle est scotchée dans un raisonnement d'habitude, ou qu'elle est fatiguée, etc. - c'est typique des erreurs de pilotage, CFIT, etc.)
Qu'est-ce que tu entends par "erreur de logique dans les itérations" ?
J'étends un code existant depuis deux ans, qui gaze façon coucou suisse, historiquement capable de traiter une DB, soudainement étendu par mes soins à 'n' DB.
Pour ce faire, à la fin de chaque traitement de DB, je dois alors effacer le conteneur ayant enregistré le dictionnaire de données, enregistré dans un conteneur nommé Schema.
Alors c'est le drame.
L'erreur : "attempt to tamper with cursors" (quand même :)
================================================
Dans l'ads j'ai :
---------------------------------
type Schema_Line is record
Command : Schema_Command;
Name : String;
Attribute : String;
Comment : String;
end record;
package Schema_Lines_List is new Ada.Containers.Vectors (Index_Type => Natural, Element_Type => Schema_Line);
private
Schema : Schema_Lines_List.Vector;
---------------------------------
Dans l'adb, je m'en sert à chaque nouvelle DB à ouvrir/créer pour recueillir tout le schéma de la DB. Mais à la fin du traitement d'une DB, je souhaite vider cette liste pour une éventuelle autre DB... Dans la fonction de finalisation, j'ai tout essayé, genre :
---------------------------------
C : Schema_Lines_List.Cursor := Schema.First;
Next : Schema_Lines_List.Cursor;
use Schema_Lines_List; -- < obligatoire pour gérer les opérateurs
begin
-- D'abord la procédure normale :
Schema.Clear;
-- Puis une manip de Jeffrey Carter (en sauvegardant le Curseur pour tromper le compilo)
loop
exit when C = Schema_Lines_List.No_Element;
declare
begin
Next := Schema_Lines_List.Next (C);
Schema.Delete (Position => C);
C := Next;
end;
end loop;
-- À l'envers pour éviter le déférencement (sic, cf les relations entre les curseurs, index et les élements, c'est très très lié)
for J in reverse 1 .. Schema.Last_Index loop
Schema.Delete (J);
end loop;
-- Et même un simple Delete_Last
Schema.Delete_Last;
---------------------------------
Dans tous les cas, j'ai :
-------------------------------------------------------------------------------------
Exception time : 20230907-155408
Program uptime : 0h0 0m0 0s
Program build DT stamp : build 2023-09-07 15:53:58
Program name & version : testapi v0.7
Library name & version : v22 v0.1
Start directory : /home/sr/opt/v22/bin
Home directory : /home/sr
Ada mem. alloc. (bytes): Ada Cur: [ 12540 ] Max: [ 19672 ]
All mem. alloc. (bytes): All Cur: [ 15335424 ] Max: [ 15335424 ]
raised PROGRAM_ERROR :
v22.Sql.Schema_Lines_List.Implementation.TC_Check: attempt to tamper with cursors
================================================
J'y passe des heures à codouiller des workarounds quand l'excellentissime Gautier (De Montmollin) d'un coup d’œil, "trouve la panne" (située ailleurs, dans une autre procédure), je le cite :
Hum, en effet, en lisant le code, ça a peu de chances de marcher. Il faut remercier GNAT pour transformer le "peu de chances" en "aucune chance" :-)
807 et suivants:
for I of Schema loop
...
-- Finalize
if I = Schema.Last_Element then
Finalize_Loop;
-- Update database schema version
Set_Config (DB, "Schema_Version", DB_Version);
end if;
end loop;
================================================
Dans Finalize_Loop il y a l'appel à l'effacement de tous les éléments du conteneur Schema alors qu'on est dans une boucle for I of Schema loop
Big up for Gautier et le compilateur¹, deux amis bienveillants :)
-- Stéphane RivièreIle d'Oléron - France