IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Construire un type au runtime


Sujet :

Langage Delphi

  1. #1
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 459
    Points : 3 090
    Points
    3 090
    Par défaut Construire un type au runtime
    Bonjour

    Je cherche à faire une chose qui n'est peut-être pas possible. Alors, avant de perdre mon temps, je viens demander votre avis.
    En fait, je voudrais créer un type à l'exécution et avant compilation. Un type dynamique en quelque sorte. Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    TAutorisation = (A, B, C);
    TAutorisations = set of TAutorisation;
    Le second définit un type que j'utilise ensuite mais pour le premier, si j'avais par exemple une liste de caractères 'A', 'B', 'C' , est-ce que je pourrais le reconstituer au démarrage du programme ?

    Tout ça pour gagner du temps sur une reprise de système un peu "branlicotant" !
    Sinon, je modifierai le système entier mais si je peux faire ce que je décris plus haut, j'aurai du temps pour autre chose .

  2. #2
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 773
    Points
    2 773
    Billets dans le blog
    10
    Par défaut
    Par expérience je répondrais non. Car les éléments de la clause "type" sont résolus au moment de la compilation donc avant l'exécution.

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 754
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 754
    Points : 13 340
    Points
    13 340
    Par défaut
    On peut générer un fichier pas/inc en pré-compilation (comme ici, par batch, ...), ça n'est pas un problème mais quid de l'utilisation de ce type (if ??? in Autorisations then) ?

    Ne pourrais-tu utiliser un TBits ?

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 563
    Points : 25 165
    Points
    25 165
    Par défaut
    A mon avis, tu es bon pour tout changer !


    un TAutorisations = class(TDictionnary<Char, Boolean>) et un fichier ini peut-être ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    FAutorisations := TAutorisations.Create();
    AutorisationList := IniFile.ReadString('Autorisations', 'List', '');
    for C in AutorisationList do 
      FAutorisations.Add(C, IniFile.ReadBoolean('Autorisations', C, False);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function TAutorisations.CheckAutorisation(C: Char): Boolean;
    begin
      if not TryGetValue(C, Result) then
        Result := False; 
    end;
    Même Surcharge d'opérateurs (Delphi) de IN (ne l'ayant jamais fait, j'en ignore les limites)
    il te faudra parcourir tous le code où est présent les valeurs de TAutorisation ... ce qui sera fastidieux mais suffira de compiler, le type étant supprimé, suffira de corriger tous les appels en masse

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if FAutorisations.CheckAutorisation('A') then
    begin
     
    ...
    end;
    si avec la surchage d'opérateur tu pouvais l'écrire comme ceci, cela faciliterait le refactoring même si au final, si la liste est finie dans le code, je ne vois pas bien la logique du problème, ça voudrait dire que demain tu ajoutes des autorisations mais comment auraient-elles un impact ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if 'A' in FAutorisations then
    begin
     
    ...
    end;

    Tu devrais plutôt décrire le besoin au lieu de nous proposer une solution farfelue.

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    ...
    En fait, je voudrais créer un type à l'exécution et avant compilation....
    alors je ne comprend pas ce que tu entends pas là

    il est tout à fait possible d'écrire un programme qui va produire un code Pascal que tu pourras ensuite intégrer dans ton application...ça m'arrive de le faire pour intégrer des valeurs importées depuis un fichier dans un tableau constant Par contre ça veux dire qu'ensuite tu (re)compiles ton programme, et donc ça c'est une démarche pour toi, pas pour le produit final qui utilisera uniquement le fichier compilé.

    Ensuite, tu peux inclure un interpréteur de script (PascalScript, DWScript, ...) il en existe aussi qui interprètent d'autres langages...Python par exemple, pour exécuter du code dynamique à l'exécution mais ça sera au détriment da la rapidité.

    après, un "set of" c'est juste une façon élégante de manipuler des bits, tu pourrais tout aussi bien l'écrire comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    type
      TAutorisation = Cardinal;
    const
      A = 1; // 1 shl 0
      B = 2; // 1 shl 1
      C = 4; // 1 shl 2
     
    var
      autorisation: TAutorisation;
    begin
      autorisation := A + B + C;
      if autorisation and B <> 0 then
        Dec(autorisation, B);
    end;
    et donc ajouter des autorisations, c'est juste ajouter des nombres en puissances de 2 (D = 1 shl 3 = 8) etc...

    dans mes bases de données je n'utilise que rarement les booleans, je préfère un champ Flag qui me permet d'ajouter des booleans sans changer la base, je le fais aussi parfois sur des composants Delphi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    type
      TMonComponsant = class(TComponent)
      private
       FFlags: Cardinal;
       function GetFlag(Index: integer): Boolean;
       procedure SetFlag(Index: Integer; value: Boolean);
      public
       property Visible: Boolean index 0 read GetFlag write SetFlag;
       property Enabled: Boolean index 1 read GetFlag write SetFlag;
      end;
     
    function TMonComponent.GetFlag(Index: integer): Boolean;
    begin
      Result := (FFlags and (1 shl Index)) <> 0
    end;
     
    procedure TMonComponent.SetFlag(Index: Integer; value: Boolean);
    begin
      if Value then
        FFlags: = FFlags or (1 shl Index)
      else
        FFlags := FFlags and not (1 shl Index);
    end;

  6. #6
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 459
    Points : 3 090
    Points
    3 090
    Par défaut
    re

    Alors, j'essaie juste de trouver une solution (disons une bidouille pour être franc) parce que le code existant fonctionne un peu à l'envers de ce qui devrait être.
    Le développeur avant moi était très débutant et avait basé son système d'autorisations non pas sur des utilisateurs ayant des droits, mais sur des droits composés d'utilisateurs ayant des droits identiques.
    Le problème du "set" est que l'ajout ou la modification des droits même pour un seul utilisateur impose de modifier le code et recompiler. Je sais, c'est débile mais c'est pas de ma faute
    Donc, ce qui correspond au droits, ce sont en fait les login des utilisateurs et un droits est représenté par un ensemble de différents utilisateurs.

    Comme tout ça est moche et pas pratique (surtout la gestion), j'ai ajouté un système de droits plus élaboré dans la base et surtout plus académique à mon sens.
    Une table des utilisateurs, une table des droits et une table des "droits des utilisateurs".

    Après, mon seul problème pour ne pas trop toucher au code serait de pouvoir créer ce "set" dynamiquement à partir de la base de données.
    Mais plus j'avance et plus je lis vos conseils, je vais tout remettre à plat et tant pis pour le temps que ça prendra.

    J'avais pensé à un interpréteur de script mais ça jouterait de la complexité pour celui qui prendra la suite après moi (bientôt la retraite)

    Je vais prendre le temps de refaire tout ça correctement.

    PS: Heureusement que je ne vous explique pas d'autres systèmes de gestion d'accès aux menus de l'application, vous prendriez peur

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 754
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 754
    Points : 13 340
    Points
    13 340
    Par défaut
    Donc tu ne dois pas créer un ensemble mais des constantes basées sur un ensemble existant et là ça ne poserait pas autrement de problème en pré-compilation.

    Mais est-ce vraiment un set dont tu as besoin ou un array of string ?

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    j'ai déjà repris du code assez horrible...ce qu'il est possible de faire c'est une surcouche propre sur une sous-couche moche

    exemple, la base est organisée à l'envers ? ok, mais elle permet à priori de gérer les choses...donc tu peux dans le code avoir les choses à l'endroit et c'est simplement lors de la lecture/écrire que tu passes d'un système à l'autre....c'est pas optimal, mais ça permet de ne pas tout changer (surtout si tu as plusieurs applis qui manipulent les données et que tu ne peux donc pas tout casser)

  9. #9
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 459
    Points : 3 090
    Points
    3 090
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Donc tu ne dois pas créer un ensemble mais des constantes basées sur un ensemble existant et là ça ne poserait pas autrement de problème en pré-compilation.

    Mais est-ce vraiment un set dont tu as besoin ou un array of string ?
    C'était aussi une piste. Peut-être que ça finira comme ça !

  10. #10
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 459
    Points : 3 090
    Points
    3 090
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    j'ai déjà repris du code assez horrible...ce qu'il est possible de faire c'est une surcouche propre sur une sous-couche moche

    exemple, la base est organisée à l'envers ? ok, mais elle permet à priori de gérer les choses...donc tu peux dans le code avoir les choses à l'endroit et c'est simplement lors de la lecture/écrire que tu passes d'un système à l'autre....c'est pas optimal, mais ça permet de ne pas tout changer (surtout si tu as plusieurs applis qui manipulent les données et que tu ne peux donc pas tout casser)
    Je sais qu'on est tous passés par là mais ici, tout le code est mal foutu. Fait à l'époque en D5, repris par un débutant complet qui même après quelques années ne savait pas faire une boucle "for" (et je ne plaisante pas malheureusement). C'est sur ce projet qu'une migration vers XE7 a été faite par mes soins, puis un passage envisagé de DBase vers MySQL (abandonné car trop compliqué). Moi, je suis désormais en soutien du nouvel intervenant chez le client et je lui ai appris beaucoup de choses. Néanmoins, il faut que je fasse des choses que lui pourra maintenir quand je ne serai plus là.
    Et des surcouches propres, j'en ai fait quelques-unes et ce sera sans doute la dernière

  11. #11
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    Salut

    je pense effectivement que l'utilisation d'une structure dynamique (tableau dynamique,TList,TStringList...) pourrait très bien te sortir de ce souci.

    Il te faudra peut-être récrire quelques fonctions telles que le IN, EXCLUDE, INCLUDE ... propres au container choisi.

Discussions similaires

  1. [SP-2010] Exception de type : System.Runtime.InteropServices.COMException
    Par ciresamba dans le forum SharePoint
    Réponses: 10
    Dernier message: 09/09/2013, 13h54
  2. Construire diagramme type anneau
    Par jademy dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 30/05/2013, 14h10
  3. Détermination du type au "runtime"
    Par acheo dans le forum Langage
    Réponses: 1
    Dernier message: 08/02/2010, 16h12
  4. [VB6]Puis-je construire ce type de requete?
    Par enibris dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 16/03/2006, 10h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo