In January of 2004, a poster to comp.lang.tcl asked which of the [tcl] [extension]s providing [object orientation] allowed one to define class members which were other objects. Several people submitted answers - and some of the answers provided demonstrated how the different extensions might do just that. Below, examples for [Snit], [itcl], [stooop] ([moodss] related), and [XOtcl] are provided. Are there other popular Tcl object oriented extensions to represent? ---- **[Snit]** ====== snit::type C2 { variable this variable that constructor {args} { set this [C2 %AUTO%] set that [C2 %AUTO%] } destructor { catch {$this destroy} catch {$that destroy} } method doThis {} { $this doSomething } method doThat {} { $that doSomething } } ====== [Peter Lewerin]: shouldn't it be like this: ====== snit::type C1 { option -partof method doSomething {} { puts "[$self cget -partof]'s $self doin' it" } } snit::type C2 { delegate method doThis to this as doSomething delegate method doThat to that as doSomething constructor {args} { install this using C1 %AUTO% -partof $self install that using C1 %AUTO% -partof $self $self configurelist $args } destructor { catch {$this destroy} catch {$that destroy} } } ====== **[incr Tcl]** ====== itcl::class C1 { } itcl::class C2 { variable m1 variable m2 constructor {} { set m1 [C1 #auto] set m2 [C1 #auto] } destructor { itcl::delete object $m1 $m2 } } ====== **[stooop]** ====== class C2 { proc C2 {this} { set ($this,o1) [new C1] set ($this,o2) [new C1] } proc ~C2 {this} { delete $($this,o1) $($this,o2) } class C1 { proc C1 {this} {} proc ~C1 {this} {} } } delete [new C2] ====== Note: in the example above, C1 is a class embedded in C2, but might as well be defined outside of C2, as in: ====== class C1 { proc C1 {this} {} proc ~C1 {this} {} } class C2 { proc C2 {this} { set ($this,o1) [new C1] set ($this,o2) [new C1] } proc ~C2 {this} { delete $($this,o1) $($this,o2) } } ====== **[XOTcl]** There are some posibilities '''Example 1''' (generate global objects in the constructor and refer to it via instance variables) ====== Class C1 Class C2 C2 instproc init {} { my instvar o1 o2 set o1 [C1 new] set o2 [C1 new] } C2 instproc destroy {} { my instvar o1 o2 $o1 destroy $o2 destroy next } ====== '''Example 2''' (by using anonymous nested objects. Does not need to destroy explicit the sub-objects) Sub-objects are better to implement aggregation or membership (part of, has a) ====== Class C1 Class C2 -parameter {o1 o2} C2 instproc init {} { my o1 [C1 new -childof [self]] my o2 [C1 new -childof [self]] } ====== '''Example 3''' (by using named sub-objects. Does not need to destroy explicit the sub-objects) Quite similar to C++ object members ====== Class C1 Class C2 C2 instproc init {} { C1 create [self]::o1 C1 create [self]::o2 } ====== '''Example 4''' (by using anonymous sub-objects generated via parameters. Sub-objects are destroyed automatically when container is deleted) Quite similar to example 2, but no need for a explicit constructor ====== ::xotcl::Class::Parameter C1 Class C2 -parameter { {o1 -Class C1 -default 1} {o2 -Class C1 -default 1} } ====== **[TclOO]** (By [DKF] on 22-Jan-2011) ====== oo::class create C1 oo::class create C2 { variable m1 m2 constructor {} { set m1 [C1 new] set m2 [C1 new] } destructor { $m1 destroy $m2 destroy } } ====== Or alternatively: ====== oo::class create C1 oo::class create C2 { variable m1 m2 constructor {} { set m1 [C1 create m1] set m2 [C1 create m2] } } ====== Note that in this example, the ''full'' name of m1 is `[[info object namespace $c2inst]]::m1`; this means it will be ''automatically'' destroyed when the outer container (`$c2inst`) is destroyed due to the deletion of the instance [namespace]. This is tricky (and is a trick used by [TDBC] to manage its cleanup). Also note that inside the methods of C2, the subobjects can be referred to as `m1` and `m2` because the names match the variable names. However the local names are formally arbitrary; all that's needed is for them to be in the right namespace (and it's probably a bad idea to overwrite or override any existing Tcl command). <> Object Orientation | Example | XOTcl Code | Survey