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]
}