【问题标题】:Tcl rename of the proc keyword doesn't work well in namespacesproc 关键字的 Tcl 重命名在命名空间中不能正常工作
【发布时间】:2012-09-18 13:14:34
【问题描述】:

我有以下程序:

rename proc _proc
_proc proc {name args body} {
    global pass_log_trace

    set g_log_trace "0"
    if {[info exists pass_log_trace]} {
        set g_log_trace $pass_log_trace
    }

    # simple check if we have double declaration of the same procedure
    if {[info procs $name] != ""} {
        puts "\nERROR: redeclaration of procedure: $name"
    }

    _proc $name $args $body

    if {$g_log_trace != 0} {
        trace add execution $name enter trace_report_enter
        trace add execution $name leave trace_report_leave
    }
}

此过程的目的主要是为代码中的所有过程添加入口和出口点跟踪器。但是,由于某种原因,它也删除了命名空间范围。比如这样的代码:

namespace eval bob {
    namespace eval joe {
        proc proc1 {} {}
    }
    proc proc2 {} {
        puts "proc2"
    }
}

puts "Namespace calling [info procs ::bob\::*]"

不会在bob 命名空间中创建过程,而是在全局命名空间中创建过程。 调用namespace current 总是返回::

有什么想法吗?

【问题讨论】:

标签: tcl


【解决方案1】:

当您调用_proc 时,使用uplevelnamespace current 的组合在调用上下文的命名空间前添加:

set ns [uplevel 1 {namespace current}]
_proc ${ns}::$name $args $body

这里uplevel 1 说,“在调用者的上下文中运行这个sn-p 代码”,正如您已经知道的,“namespace current”给出了调用它的命名空间的完全限定名称。

【讨论】:

  • 如果程序处于最高级别,则 $ns 将为 "::"。这段代码不会在 $name 前面创建四个 ':' 吗?
  • 即使是这样,Tcl 命名空间分隔符也是两个或多个双冒号,所以应该没有害处。
  • 我不想提出这个问题,但由于某种原因,上面的代码在第一次调用命名空间内的过程时,Tcl_eval 调用会产生错误。 Tcl_eval 返回错误消息:unknown command proc2。调用 info procs ::bob::proc2 返回正确的状态。
  • @user1476056:不确定您的期望是什么——听起来您可能正试图从全局范围内调用proc2,但显然您只在@ 内定义了proc2 987654332@ 命名空间,因此显然您必须提供完全限定名称 ::bob::proc2,或者您必须确保仅在您已经在 bob 命名空间中时才调用 proc2(来自另一个 proc bob 命名空间,或namespace eval ::bob { proc2 }
  • @Eric:我知道我必须为proc2 指定正确的命名空间。但是错误发生在调用之前。似乎_proc 已经运行并且Tcl_eval 返回错误,在proc2 被以任何形式调用之前。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多