Frage

Ich habe in TCL einen Code wie diesen gesehen:

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;
}

Es gibt drei Variablen, die im Namespace ::info definiert sind, aber dass drei Prozesse (setcount setId setRole) nicht im Namespace deklariert sind, scheint, als wären sie außerhalb von :: info definiert, ist das erlaubt?wie funktioniert das?

War es hilfreich?

Lösung

Verfahren sind definiert in der ::info namensraum.Sie liegen einfach nicht im Geltungsbereich der namespace eval, ein Befehl, der bei Bedarf nur den Namespace erstellt und dann das angegebene Skript in diesem Kontext ausführt.Die Ausführung im Kontext eines Namespace ändert die Art und Weise, wie proc platziert Befehle, die erstellt werden, wenn die Namen dieser Befehle nicht vollständig qualifiziert sind.Der Namensraum existiert unabhängig von der namespace eval nennen.Die Variablen müssen jedoch im Namespace deklariert werden;das vermeidet einige wirklich unangenehme Probleme mit der Auflösung von Variablen, die Leute auffangen können.

Persönlich schreibe ich lieber Code wie diesen:

namespace eval ::foo {
    proc bar ... {
        ...
    }
}

Aber ich weiß, dass andere Leute mit mir nicht einverstanden sind.Schreiben Sie, was Sie bevorzugen, da Tcl mit beiden Schemata einwandfrei funktioniert.

Andere Tipps

Der namespace eval Befehl

  1. Erstellt den Namespace, wenn er nicht existiert
  2. Führt den bereitgestellten Code aus diesem Namespace aus

Prozesse, die aus einem Namespace definiert werden (das sind alles Prozesse, da der Standardnamespace :: )

  • Wenn ein absoluter Namespace vorangestellt ist, wird dieser Befehl im angegebenen Namespace definiert
  • Wenn ein relativer Namespace vorangestellt ist, wird dieser Befehl relativ zum aktuellen Namespace definiert

Als solches

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 {} {}

Die folgenden Befehle werden existieren

::bob::joe::proc1
::bob::proc2
::proc3
::bob::joe::proc4
::proc5
::bob::joe::proc6
::bob::joe::proc7

Beachten Sie, dass Befehlen im globalen Namespace, wenn sie aus dem globalen Namespace aufgerufen werden, ein :: oder auch nicht.Dasselbe gilt für Befehle in jedem Namespace.

namespace eval bob {
    proc2 ;# calls ::bob::proc2
    ::proc5 ;# calls ::proc5 (proc5 in the global namespace)
    joe::proc4 ;# calls ::bob::joe::proc4
}

Es ist erwähnenswert, dass ein roher Befehlsname (ohne Namespace-Qualifikationsmerkmale) im aktuellen Namespace und dann, wenn er den Befehl dort nicht findet, im globalen Namespace sucht.

namespace eval bob {
    proc5 ;# calls ::proc5 since there is no ::bob::proc5
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top