我最近正在尝试从8.5升级到TCL8.6(是的,几年后)。我遇到一个问题,自动加载我们的itcl类。在我们的许多类中,我们使用类定义将类方法存储在与文件不同的文件中。自动装载很乐意处理这件事。在TCL8.6中,itcl遇到自动加载类方法的问题。但是,类定义是自动正确的。是否仍然可以让itcl自动加载类定义文件之外的类方法?如果我直接调用auto_load,该方法将被加载。
注意,对于下面的示例,我确实创建了tclIndex文件,并且它没有存储在auto_path中。
testClass定义文件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]]testCode
% 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
% 发布于 2021-08-10 08:11:12
问题的核心是itcl 3中的方法基本上是命令,而itcl 4中的方法绝对不是(在C级别,它们有不同的签名;方法现在有一个额外的参数来描述调用上下文,它以尊重动态行为的方式描述对象)。这清除了许多内部,但确实意味着基于命令的机制(如自动加载)将无法工作。
我认为最简单的解决方法是在主类文件末尾显式地source那些辅助定义文件(在任何正常的情况下都不会花那么长时间)。若要读取相对于当前文件的文件,请执行以下操作:
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对于运行一次的过程非常有用。)
https://stackoverflow.com/questions/68716652
复制相似问题