![]() |
namespace et variable vagabonde - Version imprimable +- Communauté Eggdrop (https://forum.eggdrop.fr) +-- Forum : Eggdrop et scripts (https://forum.eggdrop.fr/forumdisplay.php?fid=8) +--- Forum : Un peu plus loin (https://forum.eggdrop.fr/forumdisplay.php?fid=16) +--- Sujet : namespace et variable vagabonde (/showthread.php?tid=855) |
namespace et variable vagabonde - MenzAgitat - 16/01/2011 Voici un problème que vous pouvez avoir rencontré sans le comprendre ou sans vous en apercevoir. Il est susceptible de créer des conflits de variables entre plusieurs scripts, mais peut aussi bien n'avoir aucune conséquence visible bien qu'étant quand même là. Commençons par créer un array nommé testvar dans le namespace global. tcl
Nous allons maintenant tenter de créer une variable du même nom dans la déclaration du namespace testnamespace. tcl
Plutôt curieux, on a tenté de créer la variable testvar depuis l'intérieur du namespace testnamespace mais il semble que Tcl veuille la créer dans le namespace global à la place. Par conséquent, nous obtenons une erreur car on ne peut pas redéfinir une variable de type array de cette façon. Reproduisons maintenant le test mais en incluant le code dans une procédure. tcl
puis exécutons ladite procédure tcl
Là, plus d'erreur tcl
On peut constater accessoirement que la variable n'existe déjà plus. En effet, set utilisé dans une procédure crée une variable temporaire... à moins qu'elle n'ait été déclarée par variable auparavant : tcl
ou plus simplement tcl
_____________________
Que conclure de tout ça ? Le seul cas où vous devriez utiliser namespace eval est pour "déclarer" le namespace et initialiser vos variables au moyen de la commande variable. En dehors de ces variables proprement déclarées, il est plus sûr de définir vos autres variables en dehors du namespace eval (juste au cas où il existerait une variable globale du même nom). Il faut savoir que lorsque vous définissez une variable au moyen de set sans l'avoir au préalable déclarée avec variable, Tcl recherche la variable dans le namespace local, ne la trouve pas (puisqu'elle n'est pas déclarée), puis décide qu'il s'agit d'une variable globale (située dans le namespace global). Par conséquent, ce n'est pas la variable $testnamespace::testvar qui est créée, mais bien $::testvar. Pour éviter d'"égarer" vos variables dans le namespace global et ainsi risquer un conflit avec une autre variable qui porterait le même nom, voici la bonne façon de procéder : tcl
Une bonne habitude à prendre est de définir et d'appeler vos variables en précisant systématiquement leur namespace, ça élimine tout risque de confusion. L'exemple qui suit peut donc se passer de l'initialisation de la variable : tcl
Voici qui peut être pratique pour traquer la création de variables globales, et donc détecter d'éventuels problèmes de "fuites" de variables dans un script : Watching Global Variables Creation for Memory Leak Detection Source : Namespace confusion RE: namespace et variable vagabonde - galdinx - 16/01/2011 Bonsoir. Après discution avec Menz pour bien comprendre le problème, je trouve ca logique. En effet il faut bien différencier les 2 fonctions : "variable vartest" qui déclare une variable dans le namespace courant "set vartest 1" qui affecte une valeur a une variable Ainsi de la même facon qu'il est utile d'appeler des variables globales dans un namespace, par exemple : tcl
il n'est pas illogique de pouvoir les manipuler en écriture : tcl
Dans les 2 cas, le bot va voir qu'aucune variable "version" n'a été déclarée au niveau du namespace courant et donc regarder au niveau du namespace global. Le problème n'est donc pas la portabilité de la variable mais bien la déclaration implicite des variables par la fonction "set" lorsque celles-ci n'existent pas qui nous facilite trop la vie et empêche d'être vigilant sur la pré-existence de certaines variables au niveau global. Je suppose que comme d'habitude je ne suis pas clair mais Menz saura j'en suis sûr expliquer mon point de vue ; en tout cas, je ne trouve ce comportement tout à fait normal. Après, l'accessibilité et la modification de n'importe qu'elle variable de n'importe quel namespace depuis n'importe quel namespace me parait incohérent et dangereux mais il parait que ca fait partie de la philosophie des eggdrop... PS : la ligne tcl
ne fonctionne pas car la variable version est protégée mais c'était pour que tout le monde comprenne l'exemple (ou pas) RE: namespace et variable vagabonde - Artix - 16/01/2011 ^ tout comme Galdinx il a dit. TCL à tendance à faire tout un tas de "raccourcis" dont on est pas toujours conscients, et qui peuvent casser des trucs dans des cas comme ça. J'ajoute aussi que le même genre de comportement existe aussi pour les procédures: si la procédure ::salut::lol apelle la procédure "truc", et que la procéudre ::salut::truc existe, celle là sera lancée en priorité... et sinon, ::truc. RE: namespace et variable vagabonde - CrazyCat - 16/01/2011 Ca ne me choque pas d'avoir un tcl dans lequel le namespace est fermé puis ré-ouvert. Ca permet de bien séparer les parties et ça ne provoque pas d'erreur. Si on fait un énorme tcl qui peut être scindé en plusieurs fichiers (structure "modulaire" ?), on redéclarera le namespace et ça ne choquera personne, donc pourquoi ce serait génant si c'est pareil au sein du même fichier ? RE: namespace et variable vagabonde - CrazyCat - 16/01/2011 Voila, c'est bien une question de préférence, ce n'est pas une raison technique. Regarde chanrelay, je fais exactement ce que tu n'aimes pas, juste pour séparer la partie configuration de la partie "active". Et pire encore, 2 fonctions du namespace (init et deinit) sont déclarées hors du namespace. |