自动加载其他文件中的 Itcl Class 方法

Auto Loading Itcl Class Methods in Other File

我最近正尝试从 8.5 升级到 TCL 8.6(是的,晚了几年)。我 运行 遇到自动加载我们的 itcl classes 的问题。在我们的许多 classes 中,我们将 class 方法存储在与具有 class 定义的文件不同的文件中。 Auto load 很乐意处理这个问题。在 TCL 8.6 中,itcl 是 运行 自动加载 class 方法的问题。不过,class 定义已正确自动加载。是否仍然可以让 itcl 在 class 定义文件之外自动加载 class 方法?如果我直接调用auto_load,方法就会被加载

请注意,对于下面的示例,我确实手动创建了 tclIndex 文件,它没有存储在 auto_path。

测试类定义文件testClass.tcl

itcl::class testClass {

    constructor {args} {}
    destructor  {args}

    public    method foo  {}
}
itcl::body testClass::constructor {args} {
    puts "Created testClass"
}
itcl::body testClass::destructor {args} {
}

testClass Foo 方法定义文件testClassFoo.tcl

itcl::body testClass::foo {args} {
    puts "Bar"
}

tclIndex 文件

set dir /opt/tclClassTest
set auto_index(testClass) [list source [file join $dir testClass.tcl]]
set auto_index(::testClass::constructor) [list source [file join $dir testClass.tcl]]
set auto_index(::testClass::destructor) [list source [file join $dir testClass.tcl]]
set auto_index(::testClass::foo) [list source [file join $dir testClassFoo.tcl]]

测试代码

% puts $tcl_version
8.6
% package require itcl
4.2.1
% source /opt/tclClassTest/tclIndex
source /opt/tclClassTest/testClassFoo.tcl
% testClass t1
Created testClass
t1
% t1 foo
member function "::testClass::foo" is not defined and cannot be autoloaded
% auto_load ::testClass::foo
1
% t1 foo
Bar
% 

问题的核心是 itcl 3 中的方法基本上是命令,而 itcl 4 中的方法绝对不是(在 C 级别,它们具有不同的签名;方法现在有一个额外的参数来描述调用上下文,它以尊重动态行为的方式描述对象)。这清理了很多内部结构,但确实意味着基于命令的机制(例如自动加载)将不起作用。

我认为最简单的修复方法是 source 那些辅助定义文件显式地放在主 class 文件的末尾(在任何理智的情况下它真的不会花那么长时间)。要读入相对于当前文件的文件,请执行:

source [file join [file dirname [info script]] otherfile.tcl]

如果有很多,使用这样的循环:

apply {args {
    set dir [file dirname [info script]]
    foreach filename $args {
        uplevel 1 [list source [file join $dir $filename]]
    }
}} otherfile1.tcl otherfile2.tcl otherfile3.tcl

(这样做的好处是不会用与执行该循环相关的变量污染当前命名空间;apply 对于 运行-once 程序来说 非常好 .)