comment définir un proc dans l'espace de noms tcl
-
12-12-2019 - |
Question
J'ai vu du code dans TCL comme celui-ci :
namespace eval ::info {
set count 0;
set id 1;
set role admin;
namespace export *
}
proc ::info::setcount {
set ::info::count 0;
}
proc ::info::setId {
set ::info::id 1;
}
proc ::info::setRole {
set ::info::role user;
}
Il y a trois variables définies dans l'espace de noms ::info, mais que trois procs (setcount setId setRole) ne sont pas déclarés dans l'espace de noms, il semble qu'ils soient définis en dehors de ::info, est-ce autorisé ?Comment cela marche-t-il?
La solution
Les procédures sont défini dans le ::info
espace de noms.Ils ne rentrent tout simplement pas dans le champ d'application du namespace eval
, une commande qui crée simplement l'espace de noms si nécessaire, puis exécute le script donné dans ce contexte.Être exécuté dans le contexte d'un espace de noms change la façon dont proc
place les commandes qu'il crée lorsque les noms de ces commandes ne sont pas entièrement qualifiés.L'espace de noms existe indépendamment du namespace eval
appel.Les variables doivent cependant être déclarées dans l'espace de noms ;cela évite des problèmes vraiment désagréables avec la résolution de variables qui peuvent surprendre les gens.
Personnellement, je préfère écrire du code comme ceci :
namespace eval ::foo {
proc bar ... {
...
}
}
Mais je sais que d’autres personnes ne sont pas d’accord avec moi.Écrivez ce que vous préférez, car Tcl fonctionne très bien avec les deux schémas.
Autres conseils
Le namespace eval
commande
- Crée l'espace de noms s'il n'existe pas
- Exécute le code qui lui est fourni à partir de cet espace de noms
Procs définis à partir d'un espace de noms (qui sont tous des procs, puisque l'espace de noms par défaut est ::)
- Si elle est précédée d'un espace de noms absolu, définira cette commande dans l'espace de noms spécifié
- Si elle est précédée d'un espace de noms relatif, définira cette commande par rapport à l'espace de noms actuel
En tant que tel
namespace eval bob {
namespace eval joe {
proc proc1 {} {}
}
proc proc2 {} {}
proc ::proc3 {} {}
proc joe::proc4 {} {}
}
proc proc5 {} {}
proc bob::joe::proc6 {} {}
proc ::bob::joe::proc7 {} {}
Les commandes suivantes existeront
::bob::joe::proc1
::bob::proc2
::proc3
::bob::joe::proc4
::proc5
::bob::joe::proc6
::bob::joe::proc7
Notez que les commandes de l'espace de noms global, lorsqu'elles sont appelées depuis l'espace de noms global, peuvent être précédées d'un ::
ou non.Il en va de même pour les commandes dans n'importe quel espace de noms.
namespace eval bob {
proc2 ;# calls ::bob::proc2
::proc5 ;# calls ::proc5 (proc5 in the global namespace)
joe::proc4 ;# calls ::bob::joe::proc4
}
Il convient de noter qu'un nom de commande brut (sans aucun qualificatif d'espace de noms) recherchera dans l'espace de noms actuel puis, s'il n'y trouve pas la commande, dans l'espace de noms global.
namespace eval bob {
proc5 ;# calls ::proc5 since there is no ::bob::proc5
}