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 Perl Discussion :

Problème de visibilité des variables entre modules


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut Problème de visibilité des variables entre modules
    Bonjour,

    Je rencontre un problème concernant la visibilité des variables entre plusieurs modules utilisés dans un script.
    Pour essayer d'y voir plus clair, j'ai simplifié la situation en un problème similaire mais plus basique.

    J'ai un script main.pl qui utilise 2 modules, module_1.pm et module_2.pm.

    Dans chacun de ces modules sont définies et instanciées 2 variables et une fonction, qui sont exportées :

    $var_m1_1, $var_m1_2 et function_m1 dans le 1er module.

    $var_m2_1, $var_m2_2 et function_m2 dans le 2eme module.

    Je souhaite modifier ces variables de plusieurs façons :

    - les 2 variables de m1 et les 2 variables de m2 dans le scripts main.pl, par une modification directe.

    - les 2 variables de m1 modifiées dans une fonction de m2 mais appelée depuis main.pl

    - les 2 variables de m2 modifiées dans une fonction de m1 mais appelée depuis main.pl

    Comme on peut le vérifier avec les fichiers joints, les résultats ne sont pas symétriques, et je ne comprends pas pourquoi.

    J'ai sans doute mal compris la notion de portée et de visibilité des variables, mais, tout ce que j'ai pu lire sur le sujet concerne en général les blocs et les appels de fonctions, mais ne reflètent pas des situations plus compliquées que l'on rencontre dès que l'on commence à programmer des applications précises.

    Quelqu'un sait-il comment avoir une vision bien claire des différentes intéractions possibles entre les variables d'un script et celles des modules utilisés par celui-ci ainsi qu'entre les variables des modules eux-mêmes ?

    Voici le code du script main.pl
    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
    25
    26
    27
    28
    29
    30
    31
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    use lib './Modules';
    use module_1('$var_m1_1','$var_m1_2','function_m1');
    use module_2('$var_m2_1','$var_m2_2','function_m2');
     
    my $var_my_main = 1;
     
    print "\nvar_my_main=".$var_my_main."\n\n";
     
    print "Variables du module 1 :\n";
    print "var_m1_1 : ".$var_m1_1."\n";
    print "var_m1_2 : ".$var_m1_2."\n";
     
    print "\nVariables du module 2 :\n";
    print "var_m2_1 : ".$var_m2_1."\n";
    print "var_m2_2 : ".$var_m2_2."\n";
     
    &function_m1();
     
    print "\nVariables du module 2 modifees par module_1 :\n";
    print "var_m2_1 : ".$var_m2_1."\n";
    print "var_m2_2 : ".$var_m2_2."\n";
     
    &function_m2();
     
    print "\nVariables du module 1 modifees par module_2 :\n";
    print "var_m1_1 : ".$var_m1_1."\n";
    print "var_m1_2 : ".$var_m1_2."\n";
    Code de module_1.pm
    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
    package module_1;
     
    use Exporter;      # appel au module gérant la visibilité
    @ISA=('Exporter'); # hérite d'Exporter
     
    # Le tableau @EXPORT_OK est utilisé pour préciser les identificateurs qui sont visibles de l'extérieur du package.
    @EXPORT_OK=('$var_m1_1','$var_m1_2','function_m1');
     
    use module_2('$var_m2_1','$var_m2_2');
     
    $var_m1_1 = 11;
     
    $var_m1_2 = 12;
     
    sub function_m1 {
        $var_m2_1 = 121;
     
        $var_m2_2 = 122;
     
    }
     
    1;
    Code de module_2.pm
    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
    package module_2;
     
    use Exporter;      # appel au module gérant la visibilité
    @ISA=('Exporter'); # hérite d'Exporter
     
    # Le tableau @EXPORT_OK est utilisé pour préciser les identificateurs qui sont visibles de l'extérieur du package.
    @EXPORT_OK=('$var_m2_1','$var_m2_2','function_m2');
     
    use module_1('$var_m1_1','$var_m1_2');
     
    $var_m2_1 = 21;
     
    $var_m2_2 = 22;
     
    sub function_m2 {
        $var_m1_1 = 211;
     
        $var_m1_2 = 212;    
     
    }
     
    1;
    Les 3 codes sont dans le zip joint

    Le résultat obtenu en lançant le script : perl main.pl est :


    Pourquoi les variables de module_1 n'ont pas été modifiées par la fonction de module_2 ?
    Fichiers attachés Fichiers attachés

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Utilise (dans tous tes fichiers), use strict et use warnings.
    Ceci t'obligera, entre autre, à déclarer toutes tes variables.
    Ainsi, tu constateras qu'il te faut déclarer tes variables, et pour qu'elles soient 'exportables', tu devras les déclarer our.

    Cela dit, si tes modules (sensés être "le plus indépendant possible") ne devraient pas avoir besoin "l'un de d'autre". Cela reflète, selon moi, un problème de conception.

    Pour finir, tu ne devrais pas partager tes variables globales entre modules. Il m'apparait bien plus simple de définir tes modules sous forme de programmation objet. Tes variables seraient alors soit faisant partie d'instances d'objet, soit étant des variables de classe. Tu pourrais alors t'obliger à n'accéder à ces variables qu'à l'aide d'accesseur, et ainsi, les conserver locales à chaque module, limitant ainsi les effets de bords.

  3. #3
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut
    Merci philou67430,

    J'espère que tu me pardonneras le layus suivant, mais j'ai besoin de décrire ma frustration de programmeur modeste !

    Utilise (dans tous tes fichiers), use strict et use warnings.

    Depuis un certain temps, je me suis imposé ce comportement.
    Est-ce que ça veut dire aussi dans les modules ? Dans ce cas à quel niveau placer les deux "use" ?

    Ainsi, tu constateras qu'il te faut déclarer tes variables, et pour qu'elles soient 'exportables', tu devras les déclarer our.

    Merci pour cette précision, car c'est la 1ère fois que j'entrevoie le rôle de la déclaration des variables avec 'our'.
    Si je comprends bien, déclarer une variable avec our dans un module permet de l'exporter, sans qu'elle soit globale ? Alors que si je la déclarais avec 'my' elle ne pourrait pas être visible même en tentant une exportation ?

    Revenons sur mon exemple.

    Cela dit, si tes modules (sensés être "le plus indépendant possible") ne devraient pas avoir besoin "l'un de d'autre". Cela reflète, selon moi, un problème de conception.

    Je suis entièrement d'accord, et je n'ai aucun problème à admettre que je rencontre effectivement des soucis de "conception" .
    Mon exemple avait pour but de montrer dans quelle situation je me retrouve lorsque j'essaie de restructurer un script qui commence à grossir.
    Je vais essayer de présenter les choses autrement.

    Je suis conscient que lorsque l'on rencontre des problèmes de conception, c'est que le projet a été mal travaillé en amont. Cependant, il n'est pas toujours possible de tout prévoir à l'avance, et parfois, certaines nouvelles fonctionnalités s'imposent d'elles-même au cours de la mise en place du projet.

    Au fur et à mesure de ma progression en Perl, je suis parvenu à isoler les bouts de code répétitifs dans des fonctions, et à placer ces dernières dans des modules. Ainsi, j'ai pu réutiliser des modules facilement, car mes fonctions effectuant des opérations pas trop "compliquées", le passage des paramètres nécessaires à la fonction était suffisant pour le bon fonctionnement de l'ensemble.

    Mais depuis quelques temps je rencontre de nouvelles difficultés. Je me suis mis à la programmation Tk, et voilà à peu près comment je me retrouve dans la situation que j'essayais de décrire dans l'exemple.

    J'ai commencé à programmer une petite interface en Tk, pour manipuler des bases de données MySQL. J'ai commencé à programmer une maquette, en mettant en place quelques menus et fonctions, le tout dans un script principal. Puis, le script grossissant et des morceaux de code devant être utilisés plusieurs fois, comme je l'ai déjà fait auparavant, j'ai placé ces bouts de code dans des fonctions placées dans un ou plusieurs modules. Mais là, la situation se corse.

    En effet, dans mon interface graphique j'utilise des widgets pour afficher des zones de texte, des labels et d'autres types de widgets. Lorsque le code d'une fonction était encore dans le script principal, l'accès à ces widgets ne posait pas de problème. Mais une fois le code exporté vers les modules, c'est une autre histoire. Car, les variables déclarées avec 'my' dans le script principal ne sont plus visibles depuis les modules, et j'ai cru comprendre que l'exportation n'est pas possible pour le script principal (ça marche uniquement avec les modules, non ?).

    En découvrant le mécanisme d'exportation des variables par les modules, j'ai franchi une nouvelle étape et une première modification me permet de faire fonctionner l'ensemble à nouveau, de manière à priori plus structurée, mais pas forcément très bien conçue à mon goût.

    A présent j'ai toujours mon strict principal, bd.pl, dans lequel sont définis les objets de l'interface et certaines fonctionnalités. Puis, j'ai créé un module, bd_var.pm dans lequel je place la déclaration des variables dont je pense avoir besoin ailleurs que dans bd.pl, je les exporte, et bien sûr je supprime leur déclaration de bd.pl. Ainsi, lorsqu'une fonction d'un autre module à besoin d'utiliser une variable, j'utilise 'use bd_var.pm' en début du module, et j'importe les variables nécessaires. C'est mieux qu'avant car mon code est quand-même regroupé par fonctions et par modules en fonction de leur nature, mais ça signifie aussi que si je voulais réutiliser un de ces modules dans une nouvelle application, il faudrait également utiliser bd_var.pm... et donc l'indépendance des modules n'est plus assurée.

    D'autre part, pour les widgets utilisés dans le script principal, il est légitime de pouvoir y accéder depuis n'importe quel endroit du code. Donc, il me faut aussi exporter la création des objets widgets dans mon module particulier bd_var.pm. Et là, je n'utilise pas les avantages de la programmation objet.

    Une question me vient donc tout de suite. Lorsque l'on utilise Tk, où doit on construire les widgets ? Que mettre dans le script principal ? Comment doit-on structurer le projet dès le début, pour pouvoir le maintenir facilement et l'enrichir à moindres frais ?

    Il m'apparait bien plus simple de définir tes modules sous forme de programmation objet. Tes variables seraient alors soit faisant partie d'instances d'objet, soit étant des variables de classe. Tu pourrais alors t'obliger à n'accéder à ces variables qu'à l'aide d'accesseur, et ainsi, les conserver locales à chaque module, limitant ainsi les effets de bords.

    A ce stade d'avancement de mon projet, est-ce que ça ne va pas être trop compliqué de le transformer en version POO ?

    Connais-tu un bon tutoriel qui me permettrait de franchir l'étape de la POO sans trop de difficultés ?

    Merci

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Citation Envoyé par Krys006 Voir le message
    Merci philou67430,

    J'espère que tu me pardonneras le layus suivant, mais j'ai besoin de décrire ma frustration de programmeur modeste !

    Utilise (dans tous tes fichiers), use strict et use warnings.

    Depuis un certain temps, je me suis imposé ce comportement.
    Est-ce que ça veut dire aussi dans les modules ? Dans ce cas à quel niveau placer les deux "use" ?
    Peu importe en fait, puisque perl exécute en premier lieu tous les use d'un fichier. Le mieux est de les mettre en tout début (juste après package par exemple), histoire de ne pas les oublier.

    Ainsi, tu constateras qu'il te faut déclarer tes variables, et pour qu'elles soient 'exportables', tu devras les déclarer our.

    Merci pour cette précision, car c'est la 1ère fois que j'entrevoie le rôle de la déclaration des variables avec 'our'.
    Si je comprends bien, déclarer une variable avec our dans un module permet de l'exporter, sans qu'elle soit globale ? Alors que si je la déclarais avec 'my' elle ne pourrait pas être visible même en tentant une exportation ?
    C'est cela. Il faut décoréler la portée des variables qui, pour my comme pour our, est déterminée par le bloc qui l'englobe, de l'aspect privé/publique (qui induit un mode de stockage différent).

    Ce qui différencie our et my, c'est la représentation en mémoire des variables. Avec my, la variable est privée au package courant. Avec our, la variable possède une existence dans la table des symboles du package. C'est une variable de paquetage (ce qui fait que l'on parle de variable globale pour our, et locale pour my). Une variable our déclarée avec our possède en fait un nom complet constitué du nom de package (vide si c'est le programme principal) suivi de :: et du nom de la variable :
    Exemple :
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ perl -e 'use strict;use warnings;our $a = "toto"; my $b = "titi";print $::a, "\n", $::b, "\n"'
    Name "main::b" used only once: possible typo at -e line 1.
    toto
    Use of uninitialized value $b in print at -e line 1.
    [quote]
    Ainsi, d'un module à l'autre, il est possible d'accéder à une variable d'un autre module en la référençant par son nom complet.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ perl -e 'use strict;use warnings;{ package A; our $a = "toto"; 1; } package main; print $A::a, "\n", $a, "\n" '
    Name "main::a" used only once: possible typo at -e line 1.
    toto
    Use of uninitialized value $a in print at -e line 1.
    Ici, on voit qu'il est possible d'accéder à $a définie dans le module A depuis le module main, mais seulement en la référençant par son nom complet $A::a. La portée de $a étant limité aux accolades qui l'entoure, $a n'est plus visible dans main. Pour pouvoir utiliser dans main la variable $a sous cette forme simple, il faudrait l'avoir exportée à l'aide du module Exporter (et importée à l'aide de l'instruction require) :
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ perl -e 'use strict;use warnings;{ package A; use Exporter; BEGIN { our @ISA=qw(Exporter);our @EXPORT = qw($a) };our $a = "toto";
     1; } package main; use A; print $A::a, "\n", $a, "\n" '
    toto
    toto
    Ici, on voit que $a est exportée dans main sous un nom simple (il s'agit en fait alias de la variable $A::a).

    Revenons sur mon exemple.

    Cela dit, si tes modules (sensés être "le plus indépendant possible") ne devraient pas avoir besoin "l'un de d'autre". Cela reflète, selon moi, un problème de conception.

    Je suis entièrement d'accord, et je n'ai aucun problème à admettre que je rencontre effectivement des soucis de "conception" .
    Mon exemple avait pour but de montrer dans quelle situation je me retrouve lorsque j'essaie de restructurer un script qui commence à grossir.
    C'est une problématique récurrente, surtout dans le cas d'utilisation de langages de script, qui servent souvent à prototyper, et dont le prototype devient petit à petit, une application complète et indispensable.
    ...
    En effet, dans mon interface graphique j'utilise des widgets pour afficher des zones de texte, des labels et d'autres types de widgets. Lorsque le code d'une fonction était encore dans le script principal, l'accès à ces widgets ne posait pas de problème. Mais une fois le code exporté vers les modules, c'est une autre histoire. Car, les variables déclarées avec 'my' dans le script principal ne sont plus visibles depuis les modules, et j'ai cru comprendre que l'exportation n'est pas possible pour le script principal (ça marche uniquement avec les modules, non ?).
    Si, des variables our définies dans un module main sont exportables.
    Pour cela, il faut que les modules qui les utilisent les référencent avec leur nom complet. Exemple :
    Code du main (la ligne package main est optionnelle) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    package main;
     
    our $widget_text = Tk::Text->new();
     
    # ...
    Code du module
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    package tartanpion;
     
    sub show_text {
      $::widget_text->show();
    }
    (les méthodes et classes sont bidons)

    En découvrant le mécanisme d'exportation des variables par les modules, j'ai franchi une nouvelle étape et une première modification me permet de faire fonctionner l'ensemble à nouveau, de manière à priori plus structurée, mais pas forcément très bien conçue à mon goût.

    A présent j'ai toujours mon strict principal, bd.pl, dans lequel sont définis les objets de l'interface et certaines fonctionnalités. Puis, j'ai créé un module, bd_var.pm dans lequel je place la déclaration des variables dont je pense avoir besoin ailleurs que dans bd.pl, je les exporte, et bien sûr je supprime leur déclaration de bd.pl. Ainsi, lorsqu'une fonction d'un autre module à besoin d'utiliser une variable, j'utilise 'use bd_var.pm' en début du module, et j'importe les variables nécessaires. C'est mieux qu'avant car mon code est quand-même regroupé par fonctions et par modules en fonction de leur nature, mais ça signifie aussi que si je voulais réutiliser un de ces modules dans une nouvelle application, il faudrait également utiliser bd_var.pm... et donc l'indépendance des modules n'est plus assurée.
    Comme expliqué précédemment, tu n'es pas obligé de créer un module pour exporter tes variables du script main.

    D'autre part, pour les widgets utilisés dans le script principal, il est légitime de pouvoir y accéder depuis n'importe quel endroit du code. Donc, il me faut aussi exporter la création des objets widgets dans mon module particulier bd_var.pm. Et là, je n'utilise pas les avantages de la programmation objet.

    Une question me vient donc tout de suite. Lorsque l'on utilise Tk, où doit on construire les widgets ? Que mettre dans le script principal ? Comment doit-on structurer le projet dès le début, pour pouvoir le maintenir facilement et l'enrichir à moindres frais ?
    J'imagine que si l'application est importante, il faut s'inspirer du modèle de conception MVC (Model View Controller) qui séparer la partie modèle (base de donnée), de la vue (l'interface homme-machine) et controle (fonctionnel de l'application, qui peut, si elle n'est pas trop grosse, être implémentée dans le package main), et ainsi, concevoir la partie Tk comme un package "View" (ou plusieurs si l'application est vraiment grosse). Pour le cas d'une petite application, il est possible d'utiliser le module main pour la partie IHM, et afin de simplifier l'exportation des widgets, créer une structure de données (hashage) contenant tous les widgets)

    Mais j'invite les concepteur/programmeur d'application graphique à compléter/moduler mon avis personnel (je n'ai pas grande expérience dans les applications graphiques).

    Il m'apparait bien plus simple de définir tes modules sous forme de programmation objet. Tes variables seraient alors soit faisant partie d'instances d'objet, soit étant des variables de classe. Tu pourrais alors t'obliger à n'accéder à ces variables qu'à l'aide d'accesseur, et ainsi, les conserver locales à chaque module, limitant ainsi les effets de bords.

    A ce stade d'avancement de mon projet, est-ce que ça ne va pas être trop compliqué de le transformer en version POO ?
    A mes yeux, non, car je vois la programmation OO en perl comme une simplification de l'utilisation des modules : plus besoin d'exporter des variables ou des fonctions (l'exportation des méthodes est automatique). La seule contrainte est d'ajouter à chaque fonction (devenue méthode d'objet), un premier paramètre référençant l'objet traité, et à créer une méthode new.

    Connais-tu un bon tutoriel qui me permettrait de franchir l'étape de la POO sans trop de difficultés ?
    Ils existent dans la doc perl : perlboot, perltoot, perltooc, perlbot (en français ici : http://perl.enstimac.fr/DocFr.html).

  5. #5
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut
    Merci,

    C'est cela. Il faut décoréler la portée des variables qui, pour my comme pour our, est déterminée par le bloc qui l'englobe, de l'aspect privé/publique (qui induit un mode de stockage différent).

    Ce qui différencie our et my, c'est la représentation en mémoire des variables. Avec my, la variable est privée au package courant. Avec our, la variable possède une existence dans la table des symboles du package. C'est une variable de paquetage (ce qui fait que l'on parle de variable globale pour our, et locale pour my). Une variable our déclarée avec our possède en fait un nom complet constitué du nom de package (vide si c'est le programme principal) suivi de :: et du nom de la variable :
    Donc les variables my sont des variables privées au package.
    Peut-on parler de variable publique pour les déclarations avec our, ou doit-on seulement s’en tenir à une représentation en mémoire différente ?
    Est-ce que « privé » et « publique » sont des termes plutôt réservés au langage C par exemple ?

    Ainsi, d'un module à l'autre, il est possible d'accéder à une variable d'un autre module en la référençant par son nom complet.
    Du point de vue de la conception, on pourrait dire que c’est similaire à l’exportation de variables entre 2 modules, dans les 2 sens, démarche proscrite dans ta réponse précédente ?

    Si, des variables our définies dans un module main sont exportables.
    Pour cela, il faut que les modules qui les utilisent les référencent avec leur nom complet. Exemple :
    Code du main (la ligne package main est optionnelle) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    package main;
     
    our $widget_text = Tk::Text->new();
     
    # ...
    Code du module
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    package tartanpion;
     
    sub show_text {
      $::widget_text->show();
    }
    (les méthodes et classes sont bidons)
    OK, je découvre des possibilités que j’ignorais complètement. Du coup, mon module réservé à l’exportation des variables globales n’a plus de raison d’être (et c’est tant mieux).
    Cependant, mon esprit un peu tordu ne peut s’empêcher de se poser la question suivante :
    Puisque l’on peut accéder aux variables our entre les différents modules d’une même application, en utilisant leurs noms complets, pourquoi avoir mis en place le mécanisme d’exportation avec use Exporter ?

    J'imagine que si l'application est importante, il faut s'inspirer du modèle de conception MVC (Model View Controller) qui séparer la partie modèle (base de donnée), de la vue (l'interface homme-machine) et controle (fonctionnel de l'application, qui peut, si elle n'est pas trop grosse, être implémentée dans le package main), et ainsi, concevoir la partie Tk comme un package "View" (ou plusieurs si l'application est vraiment grosse). Pour le cas d'une petite application, il est possible d'utiliser le module main pour la partie IHM, et afin de simplifier l'exportation des widgets, créer une structure de données (hashage) contenant tous les widgets)
    Je vais me renseigner sur le modèle MVC.
    En ce qui concerne le dernier point, est-ce que tu veux dire créer un hash du type :
    our %widgets = ( $widget_1 => $ref_widget_1, $widget_2 => $ref_widget_2, … ) ; que l’on exporte avec use Exporter ?

    Ils existent dans la doc perl : perlboot, perltoot, perltooc, perlbot (en français ici : http://perl.enstimac.fr/DocFr.html).
    J’ai vu dans le livre « Perl moderne » que les auteurs mettaient pas mal en avant le module Moose, qu’en penses-tu ?

    Merci.

    Krys006

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Citation Envoyé par Krys006 Voir le message
    Merci,
    Donc les variables my sont des variables privées au package.
    Peut-on parler de variable publique pour les déclarations avec our, ou doit-on seulement s’en tenir à une représentation en mémoire différente ?
    Est-ce que « privé » et « publique » sont des termes plutôt réservés au langage C par exemple ?
    Je pense, personnellement, qu'il faut se limiter, dans un premier temps, à considérer qu'une variable our (ou local) fait partie de la table des symboles du package dans lequel elle est déclarée, la rendant "potentiellement" exportable.
    Du point de vue de la conception, on pourrait dire que c’est similaire à l’exportation de variables entre 2 modules, dans les 2 sens, démarche proscrite dans ta réponse précédente ?
    Il faut comprendre la chose suivante, en perl : une variable our possède est une variable de package, dont l'utilisation, dans le package qui la défini peut se faire à l'aide de son nom simple, mais qui peut toujours être utilisée ailleurs en utilisant son nom complet (package::nom_simple).

    Ce qui n'est pas recommandé, ce sont des dépendances croisées entre modules (l'un ayant besoin de l'autre et vice-versa). Dans certains cas (pas toujours heureusement), l'ordre des use (et des require) est important pour que les inter-dépendances puissent se faire sans problème (je n'ai pas d'exemple à proposé, mais j'ai déjà rencontré ce problème). Parfois même, le problème est insoluble (il faut alors redéfinir le périmètre des modules).

    Cependant, mon esprit un peu tordu ne peut s’empêcher de se poser la question suivante :
    Puisque l’on peut accéder aux variables our entre les différents modules d’une même application, en utilisant leurs noms complets, pourquoi avoir mis en place le mécanisme d’exportation avec use Exporter ?
    L'exportation (à l'aide du module Exporter), est une manière de rendre apparemment locale au package utilisateur, une variable d'un autre package, en permettant d'utiliser dans ce package, son nom simple. La magie d'Exporter, est de créer un alias entre la variable importée (et son nom simple) et la variable exportée (avec son nom complet).
    C'est donc tout l'intérêt de ce module d'exportation.

    Je vais me renseigner sur le modèle MVC.
    En ce qui concerne le dernier point, est-ce que tu veux dire créer un hash du type :
    our %widgets = ( $widget_1 => $ref_widget_1, $widget_2 => $ref_widget_2, … ) ; que l’on exporte avec use Exporter ?
    Ca peut être une solution, tout à fait (tu peux envisager de créer une classe GUI qui implémente un objet de type hash contenant ce que tu décrit, et que tu peux manipuler à l'aide de méthodes add_widget, find_widget, remove_widget, ...)

    J’ai vu dans le livre « Perl moderne » que les auteurs mettaient pas mal en avant le module Moose, qu’en penses-tu ?
    J'en ai aussi entendu du bien. Moose préfigure ce que sera la POO dans perl6, de ce que j'en ai compris.
    Je ne peux en dire plus, car je ne l'ai jamais utilisé. Moose offre des facilités de programmation OO, comme la création automagique des accesseurs et constructeurs...

  7. #7
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut
    Un grand merci Philou67430 pour tes réponses rapides et de grande qualité.
    Je vais essayer de mettre en application tous ces conseils.

    Krys006

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

Discussions similaires

  1. problème de visibilité des variables
    Par elhem dans le forum C#
    Réponses: 3
    Dernier message: 18/08/2009, 22h07
  2. Problème GUI et visibilité des variables
    Par amarion dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 02/07/2008, 15h00
  3. Problème de visibilité des variables globales
    Par imaril dans le forum MATLAB
    Réponses: 3
    Dernier message: 21/04/2008, 02h20
  4. problème de visibilité des variables dans un include
    Par d1g-2-d1g dans le forum Langage
    Réponses: 6
    Dernier message: 28/11/2005, 09h35
  5. [EasyPHP] problème de visibilité des variable dans les includes
    Par d1g-2-d1g dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 4
    Dernier message: 23/10/2005, 01h55

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