namespace

 

namespace - Crée et manipule des contextes pour les commandes et variables

SYNTAXE

 namespace ?option? ?arg ...?

DESCRIPTION

La commande namespace vous permet de créer, d’accéder, et de détruire des contextes séparés pour les commandes et variables. Voir la section 'QU'EST CE QU'UN NAMESPACE?' ci-dessous pour un bref aperçu des namespaces. Les options légales sont listées ci-dessous. Notez que vous pouvez abréger les options.

namespace children ?namespace? ?pattern? Renvoie une liste de tous les namespaces enfants qui appartiennent à namespace. Si namespace n'est pas spécifié, alors les enfants sont renvoyés pour le namespace courant. Cette commande retourne des noms pleinement qualifiés, qui commencent avec ::. Si l'option pattern est donnée, alors cette commande retourne seulement les noms qui correspond au modèle glob-style. Le modèle actuel utilisé est déterminé comme suit: un modèle qui commence avec :: est utilisé directement, autrement le namespace namespace (ou le nom pleinement qualifié du namespace courant) est ajouté au modèle.

namespace code script Capture le contexte namespace courant pour une exécution ultérieure du script script. Retourne un nouveau script dans lequel script aura été englobé dans une commande namespace code. Le nouveau script a deux propriétés importantes. D'abord, il peut être évalué dans tout namespace et provoquera l'évaluation de script dans le namespace courant (celui où la commande namespace code a été appelée). Deuxièmement, des arguments supplémentaires peuvent être ajoutés au script résultant et ils seront transmis à script comme arguments additionnels. Par exemple, supposez que la commande set script [namespace code {foo bar}] est appelée dans le namespace ::a::b. Ensuite eval "$script x y" peut être exécuté dans tout namespace (en supposant que la valeur de script lui ait été transmise correctement) et aura le même effet que la commande namespace eval ::a::b {foo bar x y}. Cette commande est nécessaire parce que les extensions comme Tk exécutent normalement les scripts callback dans le namespace global . Une commande visible capture une commande et son contexte namespace de façon à l'exécuter correctement plus tard. Voir la section VALEURS VISIBLES pour quelques exemples montrant comment l'utiliser pour créer des scripts callback.

namespace current Renvoie le nom pleinement qualifié pour le namespace courant. Le nom actuel du namespace global est "" (ex., une chaîne vide), mais cette commande retourne :: pour le namespace global par convénience pour les programmeurs.

namespace delete ?namespace namespace ...? Chaque namespace namespace est effacé et toutes variables, fonctions, et namespaces enfants contenus dans le namespace sont effacés. Si une fonction est en cours d'exécution dans le namespace, le namespace sera maintenu jusqu'a ce que la fonction retourne; néanmoins, le namespace est marqué pour empêcher tout autre code de le rechercher par son nom. Si un namespace n'existe pas, cette commande retourne une erreur. Si aucuns noms de namespace ne sont donnés, cette commande ne fait rien.

namespace eval namespace arg ?arg ...? Active un namespace appelé namespace et évalue tout code dans ce contexte. Si le namespace n'existe pas déjà, il est créé. Si plus d'un argument arg est spécifié, les arguments sont concaténés, séparés par des espaces de la même façon qu'avec la commandeeval, et le résultat est évalué. Si namespace a des quantificateurs namespace en tête et que les namespaces en tête n'existent pas, ils sont automatiquement créés.

namespace export ?-clear? ?pattern pattern ...? Spécifie quelles commandes sont exportées par un namespace. Le commandes exportées sont celles qui peuvent être plus tard importées dans un autre namespace en utilisant une commande namespace import. L’ensemble des commandes définies dans un namespace et des commandes que le namespace a précédemment importé peut être exporté par un namespace. La commandes n'ont pas à être définies à l'instant où la commande namespace export est exécutée. Chaque pattern peut contenir des caractères spéciaux glob-style, mais il ne peut pas inclure quelconque quantificateurs namespace. Ainsi, le modèle peut seulement spécifier des commandes dans le namespace courant (exportant). Chaque pattern est ajouté à la liste de modèles d'export du namespace. Si le flag -clear est donné, la liste de modèles d'export du namespace est réinitialisée en chaîne vide avant que quelconques pattern arguments soient ajoutés. Si aucuns patterns ne sont donnés et que le flag -clear n'est pas fourni, cette commande retourne la liste d'export du namespace courant.

namespace forget ?pattern pattern ...? Re-déplace les commandes précédemment importées d'un namespace. Chaque pattern est un nom qualifié tel que foo::x ou a::b::p*. Les noms qualifiés contiennent des ::s et qualifient un nom avec le nom d'un ou plusieurs namespaces. Chaque pattern est qualifié avec le nom d'un namespace exportant et peut avoir des caractères spéciaux glob-style dans le nom de commande à la fin du nom qualifié. Les caractères glob ne peuvent pas apparaître dans un nom de namespace. Cette commande trouve en premier les commandes exportées correspondantes. Elle vérifie ensuite si une ou plusieurs de ces commandes ont été précédemment importées par le namespace courant. Si c'est le cas, cette commande efface les commandes importées correspondantes. Ceci annule effectivement l'action d'une commande namespace import.

namespace import ?-force? ?pattern pattern ...? Importe des commandes dans un namespace. Chaque pattern est un nom qualifié comme foo::x ou a::p*. Ainsi, elle inclut le nom d'un namespace exportant et peut avoir des caractères spéciaux glob-style dans le nom de commande à la fin du nom qualifié. Les caractères glob ne peuvent pas apparaître dans un nom de namespace. Toutes les commandes qui correspondent à une chaîne pattern et qui sont couramment exportées de leurs namespace sont ajoutées au namespace courant. Ceci est fait par création d'une nouvelle commande dans le namespace courant qui pointe vers la commande exportée dans son namespace original; quand la nouvelle commande importée est appelée, elle appelle la commande exportée. Cette commande normalement retourne une erreur si une commande importée rentre en conflit avec une commande existante. Néanmoins, si l'option -force est donnée, les commandes importées remplaceront silencieusement les commandes existantes. La commande namespace import a une sémantique photographique: ainsi, seulement les commandes requises couramment définies dans le namespace exportant sont importées. En d'autres mots, vous pouvez importer seulement les commandes qui sont dans un namespace à l'instant où la commande namespace import est exécutée. Si une autre commande est définie et exportée dans ce namespace plus tard, elle ne sera pas importée.

namespace inscope namespace arg ?arg ...? Exécute un script dans le contexte d'un namespace particulier. Cette commande n'est pas sensée être utilisé directement par les programmeurs; des appels sont générés implicitement quand les applications utilisent la commande namespace code pour créer scripts callback que l’application alors enregistre avec, par ex., des widgets Tk. La commande namespace inscope ressemble plus à la commande namespace eval excepté qu'elle a une sémantique lappend et que le namespace doit déjà exister. Elle traite le premier argument comme une liste, et ajoute tout argument après le premier jusqu'à la fin comme des éléments de liste correcte. namespace inscope ::foo a x y z est équivalent à namespace eval ::foo [concat a [list x y z]] Cette sémantique lappend est importante parce que de nombreux scripts callback sont actuellement des préfixes.

namespace origin command Renvoie le nom pleinement qualifié de la commande originale à laquelle la commande importée command se réfère. Quand une commande est importée dans un namespace, une nouvelle commande est créée dans ce namespace qui pointe vers la commande actuelle dans le namespace exportant. Si une commande est importée dans une séquence de namespaces a, b,...,n où chaque namespace successif importe juste la commande du précédent namespace, cette commande retourne le nom pleinement qualifié de la commande originale dans le premier namespace, a. Si command ne se réfère pas à une commande importée, le propre nom pleinement qualifié de la commande est renvoyé.

namespace parent ?namespace? Renvoie le nom pleinement qualifié du namespace parent de namespace. Si namespace n'est pas spécifié, le nom pleinement qualifié du parent du namespace courant est renvoyé.

namespace qualifiers string Renvoie tous les quantificateurs namespace en tête de string. Les quantificateurs sont les noms de namespace séparées par ::. Pour la string ::foo::bar::x, cette commande retourne ::foo::bar, et pour :: elle retourne une chaîne vide. Cette commande est le complément de la commande namespace tail. Notez qu'elle ne vérifie pas si les noms de namespace sont, en fait, les noms des namespaces couramment définis.

namespace tail string Renvoie le simple nom à la fin d'une chaîne qualifiée. Les quantificateurs sont les noms de namespace séparées par ::. Pour la string ::foo::bar::x, cette commande retourne x, et for :: elle retourne une chaîne vide. Cette commande est le complément de la commande namespace qualifiers. Elle ne vérifie pas si les noms de namespace sont, en fait, les noms des namespaces couramment définis.

namespace which ?-command? ?-variable? name Recherche name soit comme commande ou variable et retourne son nom pleinement qualifié. Par exemple, si name n'existe pas dans le namespace courant mais existe dans le namespace global, cette commande retourne un nom pleinement qualifié dans le namespace global. Si la commande ou variable n'existe pas, cette commande retourne une chaîne vide. Si la variable a été créée mais non définie, tel qu'avec la commande variable ou au travers d'une trace sur la variable, cette commande renverra le nom pleinement qualifié de la variable. Si aucun flag n'est donné, name est traité comme un nom de commande. Voir la section RÉSOLUTION DE NOM ci-dessous pour une explication des règles concernant la résolution de nom.

QU'EST CE QU'UN NAMESPACE?

Un namespace est une collection de commandes et de variables. Il encapsule les commandes et variables pour s'assurer qu'elles ne vont pas interférer avec les commandes et variables des autres namespaces. Tcl a toujours eu une telle collection, à laquelle nous nous référerons comme le namespace global. Le namespace global contient toutes les variables globales et commandes. La commande namespace eval vous permet de créer de nouveaux namespaces. Par exemple,

 namespace eval Counter {
     namespace export bump
     variable num 0
     proc bump {} {
         variable num
         incr num
     }
 }

crée un nouveau namespace contenant la variable num et la fonction bump. Les commandes et les variables dans ce namespace sont séparées des autres commandes et variables dans le même programme. S'il y a une commande nommée bump dans le namespace global, par exemple, elle sera différente de la commande bump dans le namespace Counter.

Les variables namespace ressemblent aux variables globales en Tcl. Elles existent en dehors des fonctions dans un namespace mais peuvent être accédées dans une fonction via la commandevariable, comme montré dans l'exemple ci-dessus.

Les namespaces sont dynamiques. Vous pouvez ajouter et effacer des commandes et des variables à tout instant, et vous pouvez construire le contenu d'un namespace au fur et à mesure en utilisant une série de commandes namespace eval. Par exemple, les séries suivantes de commandes ont le même effet que les définitions namespace montrées plus haut:

 namespace eval Counter {
     variable num 0
     proc bump {} {
         variable num
         return [[incr num]]
     }
 }
     namespace eval Counter {
         proc test {args} {
             return $args
         }
     }
     namespace eval Counter {
         rename test ""
 }

Notez que la fonction test est ajoutée au namespace Counter, et enlevée plus tard via la commande rename.

Les namespaces peuvent contenir d'autres namespaces, donc être imbriqués hiérarchiquement. Un namespace imbriqué est encapsulé dans son namespace parent et ne peut pas interférer avec d'autres namespaces.

NOMS QUALIFIES

Chaque namespace a un nom textuel tel que history ou ::safe::interp. Comme les namespaces peuvent s'imbriquer, les noms qualifiés sont utilisés pour se référer à des commandes, variables, et namespaces enfants contenus dans les namespaces. Les noms qualifiés sont semblables aux noms de chemin hiérarchique des fichiers Unix ou des widgets Tk, excepté que :: est utilisé comme séparateur au lieu de '/' ou '.'. Le namespace global a pour nom "" (ex., une chaîne vide), bien que :: soit un synonyme. Comme exemple, le nom ::safe::interp::create se réfère à la commande create dans le namespace interp qui est un enfant du namespace ::safe, qui à son tour est un enfant du namespace global ::.

Si vous voulez à accéder aux commandes et variables à partir d'un autre namespace, vous devez utiliser une syntaxe supplémentaire. Les noms doivent être qualifiés par les namespace qui les contiennent. A partir du namespace global , nous accéderions à la fonction Counter comme ceci:

 Counter::bump 5
 Counter::Reset

Nous accéderions au compte courant comme ceci:

 puts "count = $Counter::num"

Quand un namespace en contient un autre, vous pouvez avoir besoin de plus d'un quantificateur pour atteindre ses éléments. Si nous avions un namespace Foo qui contenait le namespace Counter, vous pourriez appeler sa fonction bump à partir du namespace global comme ceci:

 Foo::Counter::bump 3

Vous pouvez aussi utiliser les noms qualifiés quand vous créez et renommez des commandes. Par exemple, vous pouvez ajouter une fonction au namespace Foo comme ceci:

 proc Foo::Test {args} {return $args}

Et vous pourriez déplacer la même fonction vers un autre namespace comme ceci:

 rename Foo::Test Bar::Test

Il y a quelques points restants au sujet des noms qualifiés que nous devons couvrir. Les namespaces ont des noms non-vides excepté le namespace global . '::' est interdit dans une simple commande, variable, et les noms de namespace excepté comme séparateur namespace. Les ':' supplémentaires dans un nom qualifié sont ignorés; ainsi, deux ou plus ':' sont traités comme séparateur namespace. Deux '::' à la fin d'une variable qualifiée ou d'un nom de commande se réfèrent à une variable ou commande nommée {}. Néanmoins, :: à la fin d'un nom de namespace qualifié est ignoré.

RÉSOLUTION DE NOM

En général, toute commande Tcl qui attend des noms de variable et de commande supporte les noms qualifiés. Ceci signifie que vous pouvez donner des noms qualifiés à des commandes comme set, proc, rename, et interp alias. Si vous fournissez un nom pleinement qualifié qui commence avec ::, il n'y a pas d’ambiguïté sur le sens de la commande, la variable, ou le namespace. Néanmoins, si le nom ne commence pas avec :: (ex., est relatif), Tcl suit une règle précise pour la recherche: Les noms de commandes et nom de variables sont toujours résolus en cherchant en premier dans le namespace courant, et ensuite dans le namespace global . Les noms de namespace, d'un autre point de vue, sont toujours résolus en recherchant seulement dans le namespace courant.

Dans les exemples suivants,

 set traceLevel 0
 namespace eval Debug {
     printTrace $traceLevel
 }

Tcl recherche traceLevel dans le namespace Debug et ensuite dans le namespace global. Il recherche la commande printTrace de la même façon. Si un nom de variable ou de commande n'est pas trouvé dans ce contexte, le nom est indéfini. Pour rendre ce point tout à fait clair, examinez les exemples suivants:

 set traceLevel 0
 namespace eval Foo {
     variable traceLevel 3

     namespace eval Debug {
         printTrace $traceLevel
     }
 }

Ici, Tcl recherche traceLevel en premier dans le namespace Foo::Debug. Comme il n'est pas trouvé là, Tcl le recherche alors dans le namespace global . La variable Foo::traceLevel est complètement ignorée pendant le processus de résolution de nom.

Vous pouvez utiliser la commande namespace which pour répondre aux questions au sujet de la résolution de nom. Par exemple, la commande:

 namespace eval Foo::Debug {namespace which-variable traceLevel}

retourne ::traceLevel. d'une autre manière, la commande,

 namespace eval Foo {namespace which-variable traceLevel}

retourne ::Foo::traceLevel.

Comme mentionné plus haut, les noms de namespace sont recherchés différemment des noms de variables et commandes. Les noms de namespace sont toujours résolus dans le namespace courant. Ceci signifie que, par exemple, une commande namespace eval qui crée un nouveau namespace crée toujours un enfant du namespace courant à moins que le nouveau nom de namespace commence avec un ::.

Tcl n'a pas de contrôle pour limiter quelles variables, commandes, ou namespaces vous pouvez référencer. Si vous fournissez un nom qualifié qui résolve un élément par les règles de résolution de nom plus haut, vous pouvez accéder à l'élément.

Vous pouvez accéder à une variable namespace à partir d'une fonction dans le même namespace en utilisant la commandevariable. Comme la commandeglobal, elle crée un lien local vers une variable namespace. Si nécessaire, elle crée aussi la variable dans le namespace courant et l'initialise. Notez que la commande global crée seulement des liens vers les variables dans le namespace global . Il n'est pas nécessaire d'utiliser une commande variable si vous vous referez toujours à une variable namespace en utilisant un nom qualifié approprié.

IMPORTATION DE COMMANDES

Les namespaces sont souvent utilisés pour représenter des bibliothèques. Certaines commandes de bibliothèque sont utilisées si souvent que c'est une corvée de taper leurs noms qualifiés. Par exemple, supposez que toutes les commandes dans un package comme BLT soient contenues dans un namespace appelé Blt. Ensuite vous accéderez à ces commandes comme ceci:

 Blt::graph .g-background red
 Blt::table . .g 0,0

Si vous utilisez les commandes graph et table fréquemment, vous pouvez vouloir y accéder sans le préfixe Blt::. Vous pouvez faire cela en important les commandes dans le namespace courant, comme ceci:

 namespace import Blt::*

Ceci ajoute toutes les commandes exportées du namespace Blt dans le contexte du namespace courant, donc vous pouvez écrire du code comme ceci:

 graph .g-background red
 table . .g 0,0'''

La commande namespace import importe seulement des commandes d'un namespace exporté avec une commande namespace export.

Importer toutes les commandes d'un namespace est généralement une mauvaise idée car vous ne savez pas ce que vous récupérez. Il vaut mieux importer juste les commandes spécifiques dont vous avez besoin. Par exemple, la commande

 namespace import Blt::graph Blt::table

importe seulement les commandes graph et table dans le contexte courant.

Si vous essayez d'importer une commande qui existe déjà, vous aurez une erreur. Ceci vous empêche d'importer la même commande à partir de deux packages différent. Mais de temps en temps (peut-être en débugant), vous pouvez vouloir contourner cette restriction. Vous pouvez vouloir relancer la commande namespace import pour profiter de nouvelles commandes qui ont apparu dans un namespace. Dans ce cas, vous pouvez utiliser l'option -force, et les commandes existantes seront écrasées silencieusement:

 namespace import-force Blt::graph Blt::table

Si pour quelque raison, vous voulez cesser d'utiliser les commandes importées, vous pouvez les enlever avec une commande namespace forget, comme ceci:

 namespace forget Blt::*

Ceci recherche dans le namespace courant toutes commandes importées de Blt. Si elle en trouve une, elle l'enlève. Autrement, elle ne fait rien. Après cela, les commandes Blt doivent être accédées avec le préfixe Blt::.

Quand vous effacez une commande du namespace exportant comme ceci:

 rename Blt::graph ""

la commande est automatiquement enlevée de tous les namespaces qui l'importaient.

EXPORTATION DE COMMANDES

Vous pouvez exporter des commandes d'un namespace comme ceci:

 namespace eval Counter {
     namespace export bump reset
     variable Num 0
     variable Max 100

     proc bump {{by 1}} {
         variable Num
         incr Num $by
         Check
         return $Num
     }
     proc reset {} {
         variable Num
         set Num 0
     }
     proc Check {} {
         variable Num
         variable Max
         if {$Num > $Max} {
             error "too high!"
         }
     }
 }

Les fonctions bump et reset sont exportées, donc elles sont inclues quand vous importez du namespace Counter, comme ceci:

namespace import Counter::*

Néanmoins, la fonction Check n'est pas exportée, donc elle est ignorée par les opérations d'import.

La commande namespace import importe seulement les commandes qui ont été déclarés comme exportées par leurs namespace. La commande namespace export spécifie quelles commandes peuvent être importées par d'autres namespaces. Si une commande namespace import spécifie une commande qui n'est pas exportée, la commande n'est pas importée.


VOIR ÉGALEMENT


Catégorie Manuel Tcl/Tk