tests: jimsh.tests additional tests
[jimtcl.git] / README.oo
blob8dd7a30b6f9c3d27858320b68e9b71dcd0c8b85a
1 OO Package for Jim Tcl
2 ======================
4 Author: Steve Bennett <steveb@workware.net.au>
5 Date: 1 Nov 2010 09:18:40
7 OVERVIEW
8 --------
9 The pure-Tcl oo package leverages Jim's unique strengths
10 to provide support for Object Oriented programming.
12 The oo package can be statically linked with Jim or installed
13 as a separate Tcl package and loaded with:
15   package require oo
17 DECLARING CLASSES
18 -----------------
19 A class is declared with the 'class' proc as follows.
21   class myclass ?baseclasses? classvars
23 This declares a class named 'myclass' with the given dictionary,
24 'classvars', providing the initial state of all new objects.
25 It is important to list all class variables in 'classvars', even
26 if initialised only to the empty string, since the class makes
27 these variables available in methods and via [myclass vars].
29 A list of zero or more base classes may also be specified from
30 which methods and class variables are imported. See INHERITANCE
31 below for more details.
33 Declaring a class creates a procedure with the class name along
34 with some related procedures. For example:
36   . class Account {balance 0}
37   Account
38   . info procs Account*
39   {Account get} {Account methods} {Account eval} Account {Account new} {Account destroy}
40   {Account vars} {Account classname} {Account classvars} {Account method}
42 Notice that apart from the main 'Account' procedure, all the remaining procedures (methods)
43 are prefixed with 'Account' and a space.
45 PREDEFINED CLASS METHODS
46 ------------------------
47 Declaring a class pre-defines a number of "class" methods. i.e. those which don't
48 require an object and simply return or manipulate properties of the class. These are:
50   new ?instancevars?::
51     Creates and returns new object, optionally overriding the default class variable values.
52         Note that the class name is an alias for 'classname new {}' and can be used as a shorthand
53         for creating new objects with default values.
55   method name arglist body::
56     Creates or redefines a method for the class with the given name, argument list and body.
58   methods::
59     Returns a list of the methods supported by this class, including both class methods
60         and instance methods. Also includes base class methods.
62   vars::
63         Returns a list of the class variables for this class (names
64         only). Also includes base class variables.
66   classvars::
67         Returns a dictionary the class variables, including initial values, for this class.
68         Also includes base class variables.
70   classname::
71     Returns the classname. This can be useful as [$self classname].
73 Class methods may be invoked either via the class name or via an object of the class.
74 For example:
76   . class Account {balance 0}
77   Account
78   . Account methods
79   classname classvars destroy eval get method methods new vars
80   . set a [Account]
81   <reference.<Account>.00000000000000000001>
82   . $a methods
83   classname classvars destroy eval get method methods new vars
85 PREDEFINED OBJECT METHODS
86 -------------------------
87 Declaring a class pre-defines a number of "object" methods. i.e. those which operate
88 on a specific object.
90   destroy::
91     Destroys the object. This method may be overridden, but note that it should
92         delete the object with {rename $self ""}. This method will also be called
93         if the object is reaped during garbage collection.
95   get varname::
96     Returns the value of the given instance variable.
98   eval ?locals? body::
99     Makes any given local variables available to the body, along with
100         the instance variables, and evaluate the body in that context.
101         This can be used for one-off evaluation to avoid declaring a method.
103 RESERVED METHODS
104 ----------------
105 The following methods are special
107   constructor::
108     If this method exists, it is invoked (with no arguments) after an object is created
110   unknown methodname ...::
111     If an undefined method is invoked, and this method exists, it is called with the methodname
112         and the original arguments
115 CREATING OBJECTS
116 ----------------
117 An object is created with the 'new' method, or simply by using the classname shortcut.
118 If the 'new' method is used, the variables for the newly created object (instance variables)
119 may be initialised. Otherwise they are set to the default values specified when the
120 class was declared.
122 For example:
124   . class Account {balance 0}
125   Account
126   . set a [Account]
127   <reference.<Account>.00000000000000000001>
128   . set b [Account new {balance 1000}]
129   <reference.<Account>.00000000000000000002>
130   . $a get balance
131   0
132   . $b get balance
133   1000
135 If the 'constructor' method exists, it is invoked just after the object is created
137 DECLARING METHODS
138 -----------------
139 In addition to the predefined methods, new methods may be declared, or existing
140 methods redefined with the class method, method.
142 Declaring a method is very similar to defining a proc, and the arglist
143 has identical syntax. For example:
145   . Account method show {{channel stdout}} { $channel puts "Balance of account is $balance" }
146   . $b show
147   Balance of account is 1000
149 All instance variables are available within the method and any
150 changes to these variables are maintained by the object.
152 In addition, the $self variables is defined and refers to the current object.
153 This may be used to invoke further methods on the object. For example:
155   . Account method show {} { puts "Balance of account is [$self get balance]" }
156   . $b show
157   Balance of account is 1000
159 Notes:
160 * It is a bad idea to unset an instance variable.
161 * In general, you should avoid redefining any of the pre-defined methods, except for 'destroy'.
162 * When accessing the caller's scope with upvar or uplevel, note that there
163   are two frame levels between the caller and the method. Thus it is necessary
164   to use 'upvar 2' or 'uplevel 2'
166 INHERITANCE
167 -----------
168 For each base class given in a new class declaration, the methods
169 and variables of those classes are imported into the new class being
170 defined. Base classes are imported in left to right order, so that if a
171 method is defined in more than one base class, the later definition
172 is selected. This applies similarly to class variables.
174 Within a method, 'super' may be used to explicitly invoke a
175 base class method on the object. This applies only to the *last*
176 base class given. For example:
178   # Assumes the existence of classes Account and Client
179   . Account method debit {amount} { incr balance -$amount }
180   . class CreditAccount {Client Account} {type visa}
181   CreditAccount
182   . CreditAccount method debit {amount} {
183     puts "Debit $type card"
184         super debit $amount
185   }
186   . set a [CreditAccount]
187   <reference.<Account>.00000000000000000001>
188   . $a debit 20
189   Debit visa card
190   . $a balance
191   -20
193 In the CreditAccount debit method, the call to 'super debit' invokes
194 the method 'Account debit' since Account is the last base class listed.
196 OBJECT LIFETIME/GARBAGE COLLECTION
197 ----------------------------------
198 Objects are implemented as lambdas. That is, they are procedures with state
199 and are named as references. This means that when an object is no longer
200 reachable by any name and garbage collection runs, the object will be
201 discarded and the destructor will be invoked. Note that the garbage collector
202 can be invoked manually with 'collect' if required.
204   . class Account {}
205   Account
206   . Account method destroy {} { puts dying...; rename $self "" }
207   Account destroy
208   . proc a {} { set b [Account]; return "" }
209   a
210   . a
211   . collect
212   dying...
213   1
215 CLASS METHODS/CLASS STATIC VARIABLES
216 ------------------------------------
217 All methods defined with 'method' operate on objects (instances).
218 If a class method is required, it is possible to simply declare one with 'proc'.
219 The method dispatcher will automatically be able to dispatch to this method.
220 Using this approach, it is also possible to add class static variables by
221 defining static variables to the proc. Although strictly these variables
222 are accessible only to that proc, not the class as a whole.
224 For example:
226   . class Account {}
227   Account
228   . proc {Account nextid} {} {{id 0}} { incr id }
229   Account nextid
230   . Account nextid
231   1
232   . Account nextid
233   2
234   . set a [Account]
235   <reference.<Account>.00000000000000000001>
236   . $a nextid
237   3
238   . $a eval { $self nextid }
239   4
241 HOW METHOD DISPATCH WORKS
242 -------------------------
243 All class and object methods are name "classname methodname".
245 The class method dispatcher is named "classname". When invoked with a methodname,
246 it simply invokes the method "classname methodname".
248 The method dispatch is via a two step process. Firstly the object procedure is invoked
249 with the method name. This procedure then invokes "classname method" which sets up
250 the appropriate access to the object variables, and then invokes the method body.
252 EXAMPLES
253 --------
254 tree.tcl
255 ~~~~~~~~
256 The 'tree' package is implemented using the 'oo' package.
257 See the source code in tree.tcl and a usage example in tests/tree.test
259 Of particular note is how callbacks and recursive invocation is used in the 'walk' method.
261 examples/ootest.tcl
262 ~~~~~~~~~~~~~~~~~~~
263 A comprehensive OO example is provided in examples/ootest.tcl.
265 It can be run simply as:
267   ./jimsh examples/ootest.tcl