如何在过程内部的namespace eval中访问该过程的局部变量?
在Tcl的命名空间内部访问过程参数的正确方法
我肯定是犯了个低级错误,但想请教怎么在namespace内部访问$name参数,把命名空间里的变量n设置为$name的值?我只找到过程在命名空间内时的实现方式,但反过来的情况找不到。不管试哪种写法,都会报错no such variable name。
原始报错代码:
proc getNS {name} { namespace eval ns::$name { variable n $name } }
我找到一段能运行的代码,但除非确实没法直接实现,否则这不算真正的解决方案。不过测试下来它并没有修改全局变量的问题:
proc getNS {name} { namespace eval ns::$name [list variable n $name] namespace eval ns::$name { variable a abc } } set n xyz getNS WEBS chan puts stdout "ns n: $ns::WEBS::n; a $ns::WEBS::a, global n: $n" # 输出:ns n: WEBS; a: abc; global n: xyz
问题原因
第一个代码报错的核心是变量作用域和替换时机的问题:namespace eval的花括号脚本会在目标命名空间的上下文里执行,此时$name会被解析为目标命名空间中的变量,而不是proc的局部参数name,自然会提示变量不存在。
正确的解决方案
你当前使用的[list variable n $name]写法其实就是安全且正确的方案,完全不会修改全局变量:
list会将proc参数name的当前值直接打包成脚本,传给namespace eval执行;variable n 具体值的作用是在目标命名空间中创建变量n并赋值,和全局变量n完全无关,你的测试结果已经验证了这一点。
另外还有一种更直观的写法,直接通过命名空间全称给变量赋值:
proc getNS {name} { # 直接构造命名空间变量的全称并赋值 set "ns::$name::n" $name namespace eval ns::$name { variable a abc } }
测试后同样能得到正确结果,且不会影响全局变量。
内容的提问来源于stack exchange,提问作者Gary
相关产品推荐
相关产品推荐

