次のようなクラス/サブクラスオブジェクトの階層構造を実装しようとしています。
|-- Class1 # mainClass
| |-- SubClassA # subClass
| `-- SubClassB # subClass
`-- Class2 # mainClass
|-- SubClassA # subClass
`-- SubClassB # subClass
ここでの主なポイントは、各メイン クラスで同じ名前を持つ異なるサブクラスを宣言できることです (そして、それらの変数は独立しています)。
(注: ここでは、実行中に作成されるクラスオブジェクトの階層について話しているのであって、異なるクラスの遺産についてではありません。)
Tcl に固有の高度な側面 (名前空間、スコープなど) にあまり詳しくないので、次のコードを試しました。
package require Itcl
itcl::class subClass {
variable InternalVariable
constructor {} {
puts "($this) Current namespace : [namespace current]"
puts "($this) InternalVariable scope : [itcl::scope InternalVariable]"
}
}
itcl::class mainClass {
variable SubClassesList
constructor {} {
set SubClassesList {}
puts "($this) current namespace : [namespace current]"
puts "($this) SubClassesList scope : [itcl::scope SubClassesList]"
}
method newSubClass {argName} {
lappend SubClassesList [subClass $argName]
puts "($this) SubClassesList : {$SubClassesList}"
}
}
# Create the two main classes
mainClass Class1
mainClass Class2
# Add some subclasses to Class1 and Class2
Class1 newSubClass SubClassA
Class1 newSubClass SubClassB
Class2 newSubClass SubClassC
Class2 newSubClass SubClassB
の 2 回目のオカレンスを作成するときにエラーが発生しますSubClassB
。
(::Class1) current namespace : ::mainClass
(::Class1) SubClassesList scope : @itcl ::Class1 ::mainClass::SubClassesList
(::Class2) current namespace : ::mainClass
(::Class2) SubClassesList scope : @itcl ::Class2 ::mainClass::SubClassesList
(::mainClass::SubClassA) Current namespace : ::subClass
(::mainClass::SubClassA) InternalVariable scope : @itcl ::mainClass::SubClassA ::subClass::InternalVariable
(::Class1) SubClassesList : {SubClassA}
(::mainClass::SubClassB) Current namespace : ::subClass
(::mainClass::SubClassB) InternalVariable scope : @itcl ::mainClass::SubClassB ::subClass::InternalVariable
(::Class1) SubClassesList : {SubClassA SubClassB}
(::mainClass::SubClassC) Current namespace : ::subClass
(::mainClass::SubClassC) InternalVariable scope : @itcl ::mainClass::SubClassC ::subClass::InternalVariable
(::Class2) SubClassesList : {SubClassC}
command "SubClassB" already exists in namespace "::mainClass"
変数が2つの異なるスコープを持つことができる方法を理解していないSubClassesList
が、「同じ」名前空間/名前(デバッグ出力から)があるため、おそらくクラスの名前空間についてのポイントがありません。
メソッドで新しい名前空間を作成しようとしましたnewSubClass
が、問題が解決されなかったり、いくつかの不可解な変数の名前空間エラーが追加されたりしませんでした...
method newSubClass {argName} {
set SubClassName "[namespace current]::[namespace tail $this]"
puts "($this) SubClassName : $SubClassName"
namespace eval $SubClassName "lappend SubClassesList [subClass $argName]"
puts "($this) SubClassesList : {$SubClassesList}"
}
そのようなことを実行するアイデアはありますか?
PS: [incr Tcl] を使用して、既存の環境との互換性の理由からプロジェクトにクラスを実装しましたが、他の OO 実装の方が優れている/簡単だと思う場合は、お知らせください...
編集 :
namespace eval
+を使用して、オブジェクト名に対応する新しい名前空間にオブジェクトnamespace inscope
を作成することで解決策を見つけました:subClass
mainClass
itcl::class mainClass {
variable SubClassesList
constructor {} {
set SubClassesList {}
puts "($this) current namespace : [namespace current]"
puts "($this) SubClassesList scope : [itcl::scope SubClassesList]"
# Create a new namespace corresponding to class name
namespace eval $this {}
}
method newSubClass {argName} {
# Create the subClass object in the $this namespace
lappend SubClassesList [namespace inscope $this subClass $argName]
puts "($this) SubClassesList : {$SubClassesList}"
}
}