With IncrTcl and TclOO, objects must be destroyed manually. If possible, I'd like objects to be cleaned up automatically, for example when a variable holding an object reference goes out of scope at the end of a procedure, or when a variable holding an object reference is set to say "", etc. I also want strong/weak references, to simplify management of objects in certain circumstances. I've been experimenting with a very simple OO system (owc - objects without classes) to see if I could achieve this, and what I've done so far looks like it works. Below are three examples, and at the bottom of the page are my sources - a Tcl script that implements owc, and some C code that provides support for strong/weak references. ***Example 1*** This example is a variation on http://wiki.tcl.tk/20200. ====== proc ::account::account {{ownerName undisclosed}} { set this [ocreate {deposit withdraw transfer} cleanup { variables total overdrawLimit owner }] oset $this total 0 overdrawLimit 10 owner $ownerName return $this } proc ::account::deposit {amount} { ocontext total set total [expr {$total + $amount}] } proc ::account::withdraw {amount} { ocontext total overdrawLimit owner if {($amount - $total) > $overdrawLimit} { error "Can't overdraw - total: $total, limit: $overdrawLimit" } set total [expr {$total - $amount}] } proc ::account::transfer {amount targetAccount} { ocontext total withdraw $amount ocmd $targetAccount deposit $amount return $total } proc ::account::cleanup {} { ocontext total if {$total} { puts "remaining $total will be given to charity" } } # ------------------------------------------------------------------------------ set a [::account::account "John Doe"] ocmd $a deposit 200 ocmd $a withdraw 15 puts "a = [oget $a total]" set b [::account::account] ocmd $a transfer 65 $b puts "a = [oget $a total], b = [oget $b total]" puts "Objects: [ocurrent]" set a "" puts "Objects: [ocurrent]" set b "" puts "Objects: [ocurrent]" ====== The ocurrent command returns counts of objects by namespace. The output of this script is: ====== a = 185 a = 120, b = 65 Objects: ::account 2 remaining 120 will be given to charity Objects: ::account 1 remaining 65 will be given to charity Objects: ====== As can be seen, setting variables that hold object references to "" result in the objects being cleaned. ***Example 2*** An object will only be cleaned up once all strong references to that object have been lost. In example 1, each object reference was held by only one variable, so only one variable needed to lose its reference for each object to be cleaned. This second example shows a good example of circular references which can stop objects being cleaned. Example 3 shows how this problem is fixed using weak references. These two examples are based on examples https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html%|%here%|%. ====== proc person {name} { set this [ocreate {} person_clean { variables name apartment }] oimport $this name return $this } proc person_clean {} { ocontext name puts "$name is being deinitialized" } proc apartment {number} { set this [ocreate {} apartment_clean { variables number tenant }] oimport $this number return $this } proc apartment_clean {} { ocontext number puts "$number is being deinitialized" } # ------------------------------------------------------------------------------ set john [person "John Tcler"] set number42 [apartment 42] oset $john apartment $number42 oset $number42 tenant $john puts "Objects: [ocurrent]" set john "" set number42 "" puts "Objects: [ocurrent]" ====== The output of this script is: ====== Objects: :: 2 Objects: :: 2 ====== Here, although the john and number42 variables are set to "", the second puts is still showing two objects. This is because the person and apartment objects are referring to each other. ***Example 3*** For example 2 to work, the bottom part of that script needs to be replaced with: ====== set john [person "John Tcler"] set number42 [apartment 42] oset $john apartment [weak $number42] oset $number42 tenant [weak $john] puts "Objects: [ocurrent]" set john "" set number42 "" puts "Objects: [ocurrent]" ====== This time each object gets a weak reference through the weak command. So they still have a reference to each other's object enabling them to access state, but weak references do not affect object lifetime. The output of this example is: ====== Objects: :: 2 John Tcler is being deinitialized 42 is being deinitialized Objects: ====== ***Sources*** <>Enter Category Here