Version 0 of object with scope

Updated 2015-06-25 15:50:06 by HolgerJ

HolgerJ 2015-06-25 - I was wondering whether objects can go out of scope and get deleted like they do in C++ (whenever the block ends) or in Java (when the reference count allows the garbage collection to remove it). At #EuroTcl2015 in Cologne we discussed possibilities, although objects in TclOO are commands and therefore are not tied to the block (or proc) where they have been created.

The first way discussed was tying the object to a local variable which I present as follows:

#!/bin/sh
#\
exec tclsh "$0" "$@"

package require TclOO
namespace import oo::*


# Account class from http://wiki.tcl.tk/20200 plus a little method to return current values

class create Account {
   constructor {{ownerName undisclosed}} {
       my variable total overdrawLimit owner
       set total 0
       set overdrawLimit 10
       set owner $ownerName
   }
   method deposit amount {
       my variable total
       set total [expr {$total + $amount}]
   }
   method withdraw amount {
       my variable {*}[info object vars [self]] ;# "auto-import" all variables
       if {($amount - $total) > $overdrawLimit} {
           error "Can't overdraw - total: $total, limit: $overdrawLimit"
       }
       set total [expr {$total - $amount}]
   }
   method transfer {amount targetAccount} {
       my variable total
       my withdraw $amount
       $targetAccount deposit $amount
       set total
   }
   method getInfo {} {
       my variable {*}[info object vars [self]] ;# "auto-import" all variables
       return "account of '$owner' has a total of $total."
   }
   destructor {
       my variable total
       if {$total} {puts "remaining $total will be given to charity"}
   }
} ;# class Account


proc destroyObject {objname args} {
  puts "destroyObject $objname, calling destructor"
  $objname destroy
}

# This procedure creates an object and saves its name in the variable a.
# That variable goes out of scope at the end of the procecure (Tcl has proc
# scope, not block scope - similar to JavaScript).
# The trace calls destroyObject when a goes out of scope.
proc p {} {
  set a [Account new "John Doe"]
  trace add variable a unset [list destroyObject $a]
  puts "** created object named '$a' **"
  puts "depositing 200"
  $a deposit 200
  puts [$a getInfo]
  try {
    puts "withdrawing 60"
    $a withdraw 60
  } on error e {
    puts stderr $e
  }
  puts [$a getInfo]
} ;# proc

p

puts "back in main (from proc p) and end of script."