Вы не можете напрямую делать то, что просите в 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]
}