3 # Create a class, the usual bank account, with two instance variables:
9 # We have some class methods predefined
10 # Note we can call (e.g.) either Account.methods or 'Account methods'
11 puts "---- class Account ----"
12 puts "Account vars=[Account vars]"
13 puts "Account methods=[Account methods]"
16 # Now flesh out the class with some methods
17 # Could use 'Account method' here instead
18 Account method deposit
{amount
} {
19 set balance
[+ $balance $amount]
21 Account method see
{} {
24 Account method withdraw
{amount
} {
25 if {$amount > $balance} {error "Sorry $name, can only withdraw $balance"}
26 set balance
[- $balance $amount]
28 Account method describe
{} {
29 puts "I am object $self of class [$self classname]"
30 puts "My 'see' method returns [$self see]"
31 puts "My variables are:"
32 foreach i
[$self vars
] {
37 # Now an instance, initialisition some fields
38 set a
[Account new
{name
"Bob Smith"}]
40 puts "---- object Account ----"
41 # We can use class methods on the instance too
43 puts a.classname
=[$a classname
]
47 puts "deposit 100 -> [$a see]"
50 puts "withdraw 40 -> [$a see]"
52 catch {$a withdraw
1000} res
53 puts "withdraw 1000 -> $res\n"
55 # Tell me something about the object
59 # Now create a new subclass
60 class CreditAccount Account
{
64 # Override the 'withdraw' method to allow overdrawing
65 CreditAccount method withdraw
{amount
} {
66 if {$balance - $amount < $limit} {error "Sorry $name, that would exceed your credit limit of [expr -$limit]"}
67 set balance
[- $balance $amount]
69 # Override the 'describe' method, but invoke the baseclass method first
70 CreditAccount method describe
{} {
71 # First invoke the base class 'describe'
74 puts "*** Account is in debit"
78 puts "---- class CreditAccount ----"
79 puts "CreditAccount vars=[CreditAccount vars]"
80 puts "CreditAccount methods=[CreditAccount methods]"
83 puts "---- object CreditAccount ----"
84 set b
[CreditAccount new
{name
"John White"}]
87 puts b.classname
=[$b classname
]
89 puts "initial balance -> [$b see]"
91 puts "deposit 100 -> [$b see]"
94 puts "withdraw 40 -> [$b see]"
97 puts "withdraw 1000 -> [$b see]"
100 # Tell me something about the object
104 # 'eval' is similar to 'dict with' for an object, except it operates
105 # in it's own scope. A list of variables can be imported into the object scope.
106 # It is useful for ad-hoc operations for which it is not worth defining a method.
108 $a eval total
{ incr total
$balance }
109 incr total
[$b get balance
]
110 puts "Total of accounts [$a get name] and [$b eval {return "$name (Credit Limit
: $limit)"}] is: $total"
112 # Can we find all objects in the system?
113 # Almost. We can't really distinguish those which aren't real classes.
114 # This will get all references which aren't simple lambdas.
115 puts "---- All objects ----"
116 Account new
{name
"Terry Green" balance
20}
121 foreach r
[info references
] {
122 if {[getref
$r] ne
{}} {
125 puts [format "Found %14s: Owner: %14s, Balance: %+5d, in object %s" [$self classname
] $name $balance $self]
128 puts "Not an object: $r"
137 # Let the garbage collection take care of this one