2017-08-16 1 views
0

Ceci est un cas simplifié d'un problème. J'essaye de copier une procédure à un espace de noms, de sorte qu'il utiliserait le contexte du propre espace de noms. En utilisant l'importation ne fonctionne pas (probablement parce qu'il crée simplement des alias) Voir le code ci-dessous:Copier un proc dans un espace de nom dans TCL

proc me_namespace {} { 
puts "namespace is:[namespace current]" 
puts "called namespace is:[uplevel 1 namespace current ]" 
} 
namespace eval foo {} { 
me_namespace 
puts "Now import" 
namespace import ::::me_namespace 
me_namespace 
} 

La sortie de code est:

namespace is::: 
called namespace is:::foo 
Now import 
namespace is::: 
called namespace is:::foo 
namespace is:::foo 

Idéalement, le proc me_namespace sortie 1ère ligne, après la copie, si être:

::::me_namespace 

Des idées? La seule chose à laquelle je peux penser est d'avoir les définitions de procédures dans un fichier, puis de lire le fichier et d'utiliser eval, mais je cherchais quelque chose de plus élégant. La raison pour laquelle je ne suis pas simplement utiliser uplevel, est que parfois (en particulier lors de l'utilisation variable avec uplevel est que le temps d'exécution, une fois, est beaucoup trop lent. Version TCL est 8.6

+0

La page de manuel de l'espace de noms (http://www.tcl.tk/man/tcl/TclCmd/namespace.htm) indique que l'importation ne fonctionne que sur les commandes exportées. Vous devez exporter la commande. J'ai essayé ceci et fonctionne ':: foo :: me_namespace'. Mais pourquoi auriez-vous besoin d'importer une procédure dans l'espace de noms global? –

+1

Il semble que vous implémentez une sorte de POO à l'aide d'espaces de noms. Avez-vous considéré TclOO? –

Répondre

1

procédures sont liés à leur contenant Renommez la procédure, changez sa liaison (Je déteste ça!) Pour recréer une procédure dans un autre espace de noms, vous devez soit renommer (déplacer), soit réexécuter le qui a créé l'original

Maintenant, alors que je vous recommande vraiment d'utiliser TclOO quand vous vous lancez dans ce genre de choses, vous pouvez utiliser une technique différente. ous pourrait être en mesure de l'utiliser comme ceci:

proc master_version_of_foo {ns args} { 
    namespace upvar $ns abc local1 def local2 
    # ... continue with your code in here 
} 

# Stamp out some copies 
namespace eval ::x {} 
interp alias {} ::x::foo {} ::master_version_of_foo ::x 
namespace eval ::y {} 
interp alias {} ::y::foo {} ::master_version_of_foo ::y 
namespace eval ::z {} 
interp alias {} ::z::foo {} ::master_version_of_foo ::z 

Ces vrais alias de commandes sont assez rapides, la variable de liaison est assez rapide aussi (similaire à la vitesse à la commande global; ils utilisent virtuellement les mêmes opérations de bytecode en interne) et vous partagerez la compilation de la procédure qui est elle-même assez rapide. La principale raison de ne pas faire cela est si vous avez besoin d'une résolution de commande différente dans les trois cas. À ce stade, les routes les plus rapides passent toutes par TclOO (qui apprivoise quelques-unes des capacités avancées de Tcl au point d'être utilisables) et nécessitent probablement une refonte sérieuse de votre part pour bien utiliser.

+0

Ouais, j'ai pensé au TCL OO. Mais quelqu'un a demandé un moyen "plus simple", à savoir, via l'espace de noms. Merci. – user1134991