Pergunta

Eu vi um código no TCL assim:

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

Existem três variáveis ​​definidas no namespace ::info, mas três procs(setcount setId setRole) não são declaradas no namespace, parece que estão definidas fora de ::info, isso é permitido?Como é que isso funciona?

Foi útil?

Solução

Os procedimentos são definido no ::info espaço para nome.Eles simplesmente não estão dentro do escopo do namespace eval, um comando que apenas cria o namespace, se necessário, e então executa o script fornecido dentro desse contexto.Ser executado dentro do contexto de um namespace muda a forma como proc coloca comandos que ele cria quando os nomes desses comandos não são totalmente qualificados.O namespace existe independentemente do namespace eval chamar.As variáveis ​​devem ser declaradas no namespace;isso evita alguns problemas realmente desagradáveis ​​com a resolução de variáveis ​​que podem surpreender as pessoas.

Pessoalmente, prefiro escrever código assim:

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

Mas sei que outras pessoas discordam de mim.Escreva o que preferir, pois o Tcl funciona perfeitamente com qualquer um dos esquemas.

Outras dicas

O namespace eval comando

  1. Cria o namespace se ele não existir
  2. Executa o código fornecido a partir desse namespace

Procs definidos dentro de um namespace (que são todos procs, já que o namespace padrão é ::)

  • Se precedido por um namespace absoluto, definirá esse comando no namespace especificado
  • Se precedido por um namespace relativo, definirá esse comando em relação ao namespace atual

Como tal

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

Os seguintes comandos existirão

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

Observe que os comandos no namespace global, quando chamados a partir do namespace global, podem ser precedidos por um :: ou não.O mesmo se aplica a comandos em qualquer namespace.

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

É importante notar que um nome de comando bruto (sem nenhum qualificador de namespace) procurará no namespace atual e, se não encontrar o comando lá, no namespace global.

namespace eval bob {
    proc5 ;# calls ::proc5 since there is no ::bob::proc5
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top