Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 将命名空间转换为单个进程_Oop_Tcl - Fatal编程技术网

Oop 将命名空间转换为单个进程

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

我有一组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 { } { 
    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