OTcl
目次 |
OTcl文法概説
以下の内容は必ずしも正確ではないかもしれません。悪しからず。 誤りを発見された場合、ちょちょっと直しておいて頂けると大変助かります。
OTclとは
もともとはMITで開発された、Tcl言語のオブジェクト指向拡張。派生品にXOTcl(igza'tikl)がある。 ネットワークシミュレータ ns に採用されているため、否応なく覚えることに。
- オリジナルOTclの配布サイト
- 現在OTclをメンテナンス/配布しているサイト
OTcl文法
基本はTcl。Tclコマンドは全てOTclでも使える。Tclの解説書は多く出版されているので、ここでは説明しない。
クラス定義
Class classname -superclass superclassnames
superclassnamesは、スーパークラス名を列挙したリスト。 例えば、クラスSuperClassからクラスSubClassを派生させる場合、
Class SuperClass Class SubClass -superclass SuperClass
のように書く。
クラスインスタンスの生成・破壊
インスタンスの生成は、
classname instname
もしくは
set refvar [new classname]
破壊は、
delete instname delete $refvar
インスタンスメソッドの定義
instprocコマンドを使用。
MyClass instproc methodname {arg1 arg2...} {
method body
}
インスタンスメソッドの呼び出し
インスタンス メソッド名 引数1 引数2 ... の形式。
上の例だと、
MyClass instance instance methodname These are args
あるいは、
set instref [new MyClass] $instref methodname These are args
コンストラクタ・デストラクタ及びインスタンス変数の定義
ctor, dtorは、それぞれ「init」、「destroy」という既定の名前を持つメソッド。
MyClass instproc init {args} {
$self set [fieldname] [initialval] ;# インスタンス変数の定義と初期化
eval $self next $args ;# スーパークラスのコンストラクタ呼び出し
}
親のコンストラクタは自動的には呼ばれないため、以下の形式で明示的に呼び出すこと。
eval $self next $args ;#引数のある場合 eval $self next ;#引数のない場合
たとえ最上位のクラス(-superclassをなにも指定しない)でも、上記呼び出しを行う必要がある。
デストラクタも同様。
MyClass instproc destroy {} {
body...
eval $self next ;# スーパークラスのデストラクタ呼び出し
}
たとえ最上位のクラス(-superclassを何も指定しない)でも、デストラクタで親を呼ばなければならない。呼ばなければオブジェクトが破棄されず残るので注意。
親のコンストラクタ/デストラクタが実行されるタイミングは、eval $self nextのメソッド内位置に依存する。
メソッドのオーバーロード
基本クラスのメソッドと同名のメソッドを派生クラスで再定義することができる。 基本クラスのメソッドを呼び出すには、派生クラスメソッド内で以下のように記述する。
eval $self next [args]
メソッドのオーバーライドや、同一クラス内で同名のメソッドを複数定義することは不可能である。
インスタンス変数の参照
メソッド内部から参照するには、コマンド instvar を使用。 instvarはglobalのクラス版と考えればよい。
メソッド内でのインスタンス自身への参照には、特殊変数 $self が使える。
MyClass instproc setField {val} {
$self instvar m_field
set m_field $val
# $self set m_field $val でも同じである。
}
MyClass instproc getField {} {
$self instvar m_field
return $m_field
# return [$self set m_field] でも同じである。
}
クラス外から参照する方が実は簡単だが、一応OOPなのでアクセサを定義するほうがよいだろう。
set instance [new MyClass] $instance set m_field 0 ;# set set fieldVal [$instance set m_field] ;# get
クラスメソッドの定義
クラスメソッドの概念は存在しない。
ただし、クラスオブジェクトに直接procを定義することで、類似の効果を得ることができる。
クラス変数の定義
クラス変数の概念は存在しない。
ただし、クラスオブジェクトのインスタンス変数として定義することで、類似の効果を得ることができる。
MyClass set s_classVar 0
クラス変数の参照
直接参照する場合は
set someVar [MyClass set s_classVar]
インスタンスメソッド内から参照する場合は、現在のインスタンスのクラスオブジェクトを保持する特殊変数、$class を用いて以下のように。
MyClass instproc getClassVar {} {
return [$class set s_classVar]
# $class instvar s_classVar; return $s_classVar でも同じである。
}
MyClass instproc setClassVar {val} {
$class set s_classVar $val
# $class instvar s_classVar; set s_classVar $val でも同じである。
}
リフレクション
オブジェクトのメタデータをinfoメソッドで取得可能。
class info command instance info command
たとえば
MyClass info instprocs
は、My Classの全てのインスタンスメソッド名をリストで取得
MyClass a a info vars
は、オブジェクトの持つインスタンス変数を全て列挙