【问题标题】:How to get origin of namespace used inside a Tcl Proc如何获取 Tcl Proc 中使用的命名空间的来源
【发布时间】:2013-08-02 16:33:39
【问题描述】:

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

例子:

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

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

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

【问题讨论】:

    标签: oop tcl


    【解决方案1】:

    假设您不愿意只搜索您的源代码(使用真实的过程名称很容易,但使用像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 更整洁(老实说,痕迹让我有点害怕)但我想它的侵入性要小一些……

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

    【讨论】:

    • 感谢Donal Fellows,这正是我所需要的。
    • 我害怕自己使用跟踪执行,但是对于手头任务的快速周转时间,重载 proc 就像一个魅力!再次感谢。
    【解决方案2】:

    嗯,最简单的可能是 grep。

    如果你想在纯 Tcl 中做,有几个选择:

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

    【讨论】:

    • 谢谢 Johannes,grep 是一种绷带解决方案,然后我不得不将它放到日志中,然后从该日志中解析。
    • 我需要一个基于 Tcl 的解决方案,我认为跟踪执行是可行的方法,谢谢 ..
    【解决方案3】:

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

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

    【讨论】:

    • 感谢 PHIfounder,但对于我完成的快速周转任务,当时获得套件并运行是不可行的。不过,这是个好主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    相关资源
    最近更新 更多