2010-02-04 90 views
0

假設以下代碼聲明:Tcl:在類中設置自有實例的私有變量

itcl::class ObjectA { 
    private variable m_ownedObject 
    private variable m_someVariable 

    constructor {} \ 
    { 
     set m_ownedObject [ObjectA #auto] 
    } 

    protected method SetSomeVariable {newVal} { 
     set m_someVariable $newVal 
    } 

    public method SomeMethod{} { 
     $m_ownedObject SetSomeVariable 5 
    } 
} 

這是我知道如何在m_ownedObject上的SomeMethod中修改m_someVariable的唯一方法。在其他語言中(比如說C/C++/C#/ Java),我很確定我可以這樣說:

m_ownedObject.m_someVariable = 5 

有沒有辦法在tcl中做這樣的事情,或者我是否總是需要創建受保護的getter和setter?希望這是相當清楚的。

回答

1

你不能直接做你問在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] 
} 
1

如果您將變量聲明爲私有,則表示只能從該類中進行訪問。這也適用於C/C++/Java ...所以我不確定你期待什麼。

無論如何Tcl是一種動態語言,所以你可以做那樣的事情。

itcl::class tclass { 
     foreach v {time distance} { 
     method get$v {} [subst -nocommands { return [subst $$v] }] 
     method set$v nuval [subst -nocommands { set $v \$nuval } ] 
     protected variable $v "Var $v" 
     } 
    } 

它將創建所有的getterssetters,你需要;)

您可以在這裏找到更多的信息:http://wiki.tcl.tk/17667

+0

我不知道你的理解。我從類內部訪問變量 - 我只是使用不同的實例(即不是'this')。這在其他語言中是允許的。我對此100%肯定。我剛剛在C#中進行了檢查 – Jordan 2010-02-04 18:53:29

2
$m_ownedObject configure -m_someVariable 5