您不能直接在 itcl 中执行您要求的操作。但是,这是 Tcl,您可以解决这个问题,并直接从任何地方设置成员变量。我使用了一个辅助例程memv
,你可以通过它传递一个实例和一个变量名,它会返回一个对该变量的“引用”。
这显然绕过了 Itcl 设置的私有/受保护机制,因此您违反了使用它们的抽象。是否要使用它是您的决定。我发现它对于调试非常宝贵,但不要在生产代码中使用。
示例用法是:
set [memv m_ownedObject m_someVariable] 5
的代码memv
是:
proc memv {obj varname} {
# have to look up the variable, which might be in a base class
# so do 'info variable' to get that, and the full name is the 3rd element
# next two lines handle pulling apart an array
set aindex ""
regexp -- {^(.+)\((.+)\)$} $varname ignore varname aindex
set var [lindex [$obj info variable $varname] 2]
if {$aindex == ""} {
return [list @itcl $obj $var]
} else {
return [list @itcl $obj $var\($aindex\)]
}
}
同样,我有一个名为的辅助例程memv
,它允许您调用任何方法(包括私有方法和受保护方法)。用法类似
[memf m_ownedObject SetSomeVariable] 5
它的代码是:
proc memf {obj fcnname} {
set f [$obj info function $fcnname]
if {[llength $f] != 5} {
error "expected '$obj info function $fcnname' to return something like 'private proc ::namespace::name args {...}' but got: $f"
}
set fullname [lindex [$obj info function $fcnname] 2]
set namespace [namespace qualifiers $fullname]
set function [namespace tail $fullname]
return [itcl::code -namespace $namespace $obj $function]
}