como definir um proc no namespace tcl
-
12-12-2019 - |
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?
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
- Cria o namespace se ele não existir
- 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
}