0

我有以下函数或过程 decalration,如下所示,其中 proc 名称本身是来自其他地方的命名空间,我的意思是不同的文件。我如何知道该命名空间来自哪里,意味着来自哪个文件?

例子:

proc ::a::b {some argument} {
    body
}

在上面显示的示例中,我想明确知道 ::a::b 中的名称空间“a”来自或使用的位置。它不在同一个文件中,在同一个目录中还有 100 个其他文件。

我尝试使用命名空间代码和命名空间起源,但它们都不起作用。

4

3 回答 3

2

假设您不愿意只搜索源代码(使用真实的过程名称很容易,但在使用像这样的简短示例时就不那么容易了b!)您可以通过检测什么来建立有关定义事物的位置的信息proc。这一切都有效,因为proc只是一个普通的命令

重载proc以添加跟踪

执行此操作的经典方法是重命名proc并将跟踪命令(过程)放在其位置,proc一旦完成,该命令将委托给重命名的原始命令:

rename proc _real_proc
_real_proc proc {name arguments body} {
    global definitionLocations
    if {![string match "::*" $name]} {
        set name ::[string trimleft [uplevel 1 {namespace current}]::$name ":"]
    }
    set definitionLocations($name) [file normalize [info script]]
    uplevel 1 [list _real_proc $name $arguments $body]
}

如果您将该代码放在您source的任何其他应用程序代码之前,它将准确跟踪每个过程在全局definitionLocations数组中的定义位置。

使用跟踪附加跟踪

附加此监控代码的另一种方法是使用执行跟踪:

trace add execution proc enter {apply {{arguments op} {
    global definitionLocations
    set name [lindex $arguments 1]
    if {![string match "::*" $name]} {
        set name ::[string trimleft [uplevel 1 {namespace current}]::$name ":"]
    }
    set definitionLocations($name) [file normalize [info script]]
}}}

我不确定这是否比覆盖更整洁proc(老实说,痕迹让我有点害怕)但我想它的侵入性要小一些……</p>

但是,这一点仍然适用于在定义相关程序之前仍需要附加跟踪。

于 2013-08-02T08:33:32.710 回答
0

使用 Tcl Dev Kit Cross Reference Tool (XRef ) ,如果您正在寻找命名空间所在的文件。XRef
工具扫描 Tcl 源代码,然后构建一个交叉引用数据库,显示 Tcl 代码组件之间的关系. 这些组件包括包、文件、命名空间、命令和变量。每个 Tcl 组件都以树形层次结构呈现,可以展开以显示代码的定义、声明、使用和定位的位置。

还有一些其他的交叉引用工具。

于 2013-08-02T04:11:27.683 回答
0

好吧,最简单的可能是 grep。

如果你想用纯 Tcl 来做,有几个选择:

  1. 跟踪namespace以便您知道何时调用它。您可以使用info script. 必须在创建此命名空间之前完成
  2. namespace用你自己的东西替换,就像 1 一样。必须在创建命名空间之前完成
  3. 如果此命名空间内有一个 proc 是在与创建命名空间相同的文件中创建的,则可以添加 atrace execution add enterstep并使用info frame来获取定义此 proc 的文件。以后可以做
于 2013-08-01T22:46:29.657 回答