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

Lazarus Pascal Discussion :

[0.9.29] Indirection sur une variable ? [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut [0.9.29] Indirection sur une variable ?
    Bonjour,

    Dans certains langages (Windev, .Net,... ) il est possible de faire des indirections sur une variable, c'est à dire accéder à cette dernière (en lecture et en écriture) en construisant son nom dans une chaîne de caractères.

    Par exemple :
    On supposera 2 TBitBtns sur la Form nommés BTvalid et BTquit.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
     i, nBTvalid, nBTquit : integer;
    begin
     for i:=0 to ComponentCount-1 do  begin
       if Components[i] is TBitBtn then
         ProcIndirection ('n'+TBitBtn(Components[i]).Name)) :=  i; 
         // Affectation de i aux variables nBTquit, puis nBTvalid 
         // à partir de la chaine 'n'+TBitBtn(Components[i]).Name)
     end; 
    end;
    Ici ce code a peu d'intérêt. On pourrait procéder autrement. Il est là uniquement pour illustrer ma demande.

    J'ai trouvé ceci : https://forums.embarcadero.com/threa...threadID=26774 que je n'arrive évidemment pas à transposer à mon problème puisqu'il utilise comme ruse (donc comme contrainte forte), un tableau de pointeurs "liés" au fait que les variables ont dans leur nom, une partie numérique incrémentée de manière continue P1, P2, P3. A la rigueur si je procède ainsi (btXXX0, btXXX1, btXXX2), il n'y a pas besoin d'utiliser les indirections.

    Bref, le problème reste "entier" . Existe-t-il une réponse envisageable en Lazarus ?

    Cordialement. Gilles
    Dernière modification par Invité ; 12/07/2010 à 16h47. Motif: Précision

  2. #2
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Par défaut
    A ma connaissance rien de tel n'existe en FreePascal.

    Si vraiment tu as besoin d'un système similaire il va te falloir mettre les mains dans le pâté. En gros ce qu'il te faut c'est un tableau associatif qui à une chaîne (le nom de ta variable) fait correspondre une donnée (ici un pointeur sur la variable).

    Un programme utilisant ce système pourrait ressembler à
    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
     
    program Test;
     
    uses DicoAsso;
     
    var
      A, B, C : Integer;
     
    begin
      // Préparation
      EnregistreVar('A', @A);
      EnregistreVar('B', @B);
      EnregistreVar('C', @C);
     
     
      // Utilisation
      A:=0; B:=0; C:=0;
      PInteger(LitVar('B'))^:= 5;
     
      WriteLn(A, ' ', B, ' ', C); // doit ecrire 0 5 0
    end;
    L'interface de ton unité serait du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    unit DicoAsso;
     
    interface
     procedure EnregistreVar(const S: String; P: Pointer);
     function LitVar(const S:String): Pointer);
    Il ne te reste plus qu'à écrire la partie implémentation. Pour ça du peut t'inspirer de ceci.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci pour votre réponse,

    Indispensable non. Mais, je suis en vacances donc, j'en profite...; Quand j'ai rencontré le problème, j'ai pensé naturellement Pointer. Et là, je me suis retrouvé sans idée. 2 fois en 2 semaines. Hum... et probablement pour des manques identiques.

    J'avais vu ce genre d'utilisation en Windev 7.5 avec des {} autant que je me souvienne. En faisant quelques recherches sur Internet, j'ai vu que c'était réalisable en .Net avec Imports System.Reflection dont l'équivalent n'existe pas en Lazarus. Alors comme en ce moment, je fais de grosses révisions nécessaires (cf une discussion récente) et si en possible en m'amusant -cela fait mieux passer la contrainte-, je me suis douté que je rencontrerais des class, property & co...

    OK. Je suis la piste...

    Merci beaucoup pour votre aide.
    Cordialement. Gilles

  4. #4
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Par défaut
    En POO il existe un truc qui ressemble vaguement à ce que tu veux faire : l'introspection mais il faut dejà être à l'aise avec la POO.

  5. #5
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Par défaut
    Bonsoir,
    Citation Envoyé par batyann811 Voir le message
    En POO il existe un truc qui ressemble vaguement à ce que tu veux faire : l'introspection mais il faut dejà être à l'aise avec la POO.
    Moi aussi, je cherchais à faire un truc dans ce genre (du genre java reflect) avec freepascal, j'ai pas beaucoup cherché. C'était pour faire un petit système JSON-RPC, mais finalement j'ai pris une autre solution.
    Tu sais comment on peut s'y prendre?

  6. #6
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Par défaut
    En fait je n'ai jamais utilisé l'introspection en pascal... Je sais juste que ça existe.

    Si ça peut te servir tu as des infos ici et par exemple.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Finalement,

    J'ai retenu le principe de l'introspection et je me suis créé trois composants non-visuels -histoire de faire quelques progrès en POO- lzInteger, lzString qui fonctionnent bien et lzVariant qui me pose encore quelques problèmes au niveau du contrôle des types.

    Le principe est le suivant :
    • je peux lire ainsi LireLeVariant(nil,'lzVarBTquit');
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      function TFormx.LireLeVariant(Sender: TObject;sName : string): variant;
      var
       lzvariant : TlzVariant;
      begin
       result := nil;
       lzvariant := TlzVariant(FindComponent(sName));
       if lzvariant <> nil
        result := lzvariant.value;
      end;
      et les charger ainsi : AffecterAuVariant(nil,'lzBTquit',12);
      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
      function TFormx.AffecterAuVariant(Sender: TObject;sName: string, vvalue: variant): boolean;
      var
       lzvariant : TlzVariant;
      begin
       result := true;
       lzvariant := TlzVariant(FindComponent(sName));
       if lzvariant <> nil
        result := false
       else
        try
         lzvariant.value := vvalue;
        except
         result := false;
        end;
      end;


    Bon ce n'est pas vraiment une indirection, mais cela me suffit...

    Appliqué à mon code de départ,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
     i, nBTvalid, nBTquit : integer;
    begin
     for i:=0 to ComponentCount-1 do  begin
       if Components[i] is TBitBtn then
         ProcIndirection ('n'+TBitBtn(Components[i]).Name)) :=  i; 
         // Affectation de i aux variables nBTquit, puis nBTvalid 
         // à partir de la chaine 'n'+TBitBtn(Components[i]).Name)
     end; 
    end;
    cela donne ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [...]
    nBTvalid, nBTquit définis comme TlzVariant;
    [...]
    var
     i :integer;
    begin
     for i:=0 to ComponentCount-1 do  begin
       if Components[i] is TBitBtn then
         AffecterAuVariant(nil,'n'+TBitBtn(Components[i]).Name), i); 
         // Affectation de i aux variables nBTquit, puis nBTvalid 
         // à partir de la chaine 'n'+TBitBtn(Components[i]).Name)
     end; 
    end;
    Je considère (en attendant mieux) le problème comme résolu.

    Merci encore une fois pour votre aide.
    Cordialement. Gilles
    Dernière modification par Invité ; 17/07/2010 à 19h56.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XSLT] Faire une boucle sur une variable [i]
    Par PoT_de_NuTeLLa dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 07/06/2010, 13h45
  2. [2.0] Get sur une variable d'application qui bug ??
    Par brousaille dans le forum ASP.NET
    Réponses: 8
    Dernier message: 14/03/2006, 06h08
  3. [Tableaux] action sur une variable ->
    Par mactech dans le forum Langage
    Réponses: 9
    Dernier message: 15/12/2005, 19h01
  4. Opération sur une variable
    Par pcdj dans le forum Linux
    Réponses: 2
    Dernier message: 29/10/2005, 21h02
  5. Ajouter un listener sur une variable
    Par serwol dans le forum Général Java
    Réponses: 4
    Dernier message: 14/10/2005, 16h39

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