Oop 将命名空间转换为单个进程
我有一组proc和一个名称空间,如下所示:Oop 将命名空间转换为单个进程,oop,tcl,Oop,Tcl,我有一组proc和一个名称空间,如下所示: namespace eval ::_API { if {[info exists ::_API::API_ids]} { catch {API erase -ids [array names ::_API::API_ids]} } catch {unset API_ids} array set API_ids "" } proc ::_API::erase { } { forea
namespace eval ::_API {
if {[info exists ::_API::API_ids]} {
catch {API erase -ids [array names ::_API::API_ids]}
}
catch {unset API_ids}
array set API_ids ""
}
proc ::_API::erase { } {
foreach id [array names ::_API::API_ids] {
if {::_API::API_ids($id) == 0} {
continue
}
if {[catch {API -id $id -redraw 0}] != 0} {
set ::_API::API_ids($id) 0
}
}
Redraw ;# I'm not concerned about this part
# and I'm fairly certain it can be ignored
}
proc erase { } {
::_API ::erase
}
:_API::API_ID
是一个包含点的数组(例如0 1 2 3 4 5 6 7 8 9 10 11 12 14
)。脚本所做的是删除表中的点
我想将名称空间::API
转换成一个proc,这样我就可以使用GUI按钮调用这个proc。它当前直接在一些其他脚本(映射表中的点)之后,我只想在需要时删除它们;i、 e.按下按钮的时间
我已尝试直接运行:_API::erase
,但它不起作用:
proc ::_API::erase { } {
foreach id [array names ::_API::API_ids] {
if {::_API::API_ids($id) == 0} {
continue
}
if {[catch {API -id $id -redraw 0}] != 0} {
set ::_API::API_ids($id) 0
}
}
Redraw
}
我认为名称空间中可能缺少一些东西。我试着阅读了,但我不太明白它们是如何工作的。您的意思是希望将名称空间初始化代码转换为过程。下面的示例应该可以实现这一点
namespace eval ::_API {
}
proc ::_API::initialize {} {
variable API_ids
if {[info exists API_ids]} {
catch {API erase -ids [array names API_ids]}
unset API_ids
}
array set API_ids ""
}
... more definitions ...
::_API::initialize
我们首先声明名称空间。然后在过程中复制原始代码。由于取消设置一个不存在的变量没有意义,因此我们将取消设置移动到仅在该变量存在时运行的块中。
在名称空间定义的末尾,通过调用其初始化函数来初始化名称空间。您真正需要做的第一件事是使用
变量
来声明变量。出于一些相当丑陋的原因,如果不这样做,可能会导致具有可变分辨率的“乐趣”以您意想不到的方式发生:
namespace eval ::_API {
variable API_ids; ##### <<<<<<< THIS <<<<<<< #####
if {[info exists ::_API::API_ids]} {
catch {API erase -ids [array names ::_API::API_ids]}
}
catch {unset API_ids}
array set API_ids ""
}
这大大简化了事情,事实上,您可以从耦合绘图和数据管理的角度考虑,这比我上面所做的要紧密得多;这只是说明你能做什么。(我发现当我使用对象时,它使事情变得简单了很多,因为它们比普通名称空间更具有生命周期感。)谢谢你的回复。这是正确而有力的方法。这个答案对我不适用。必须将数组名称更改为array get才能获得所需的结果。
oo::class create APIClass {
variable ids
constructor {} {
array set ids {}
}
method erase {} {
foreach id [array names ids] {
if {$ids($id) == 0} continue
if {[catch {
API -id $id -redraw 0
}]} {
set ids($id) 0
}
}
Redraw
}
# Allow something to reference the ids variable from the outside world
method reference {} {
return [my varname ids]
}
}
APIClass create _API
# [_API erase] will call the erase method on the _API object