Updated 2013-01-07 13:29:31 by dkf

dkf has been doing OO, too - here [1] is his pure-Tcl approach with the following features:

  • requires Tcl 8.5a2 or later (dict and many other features too)
  • about 16KB of size
  • prototype-based, but which has a class-based face built on top
  • in an earlier phase, presented at the 2004 Tcl convention (Powerpoint: [2] PDF: [3])

Here's the next version, oo3.tcl[4]

Current methods of the Object class/object:
Return the object's persistent state handle
? <handle>
Convert a persistent state handle to a callable object
Increment the object's reference count
as <variable>
Bind object lifetime to the lifetime of a (presumably local) variable
Produce a copy of the object, returning the name of the new object
Magic method called from new command
Decrement the object's reference count and delete if reaches zero
delegate <method> to <object>
Arrange for a method (or all unknown methods if method is *) to be executed by another object (or object-like entity like a Tk widget)
Delete the object, calling any destructor defined
derive <class> ?namespace? <definition>
Create a new object through subclassing
Callback for when the object is deleted
eq <object>
Is the argument object equal to this object?
get <field> ?key?
Read an object field
get parent
Return the parent/superclass object, or empty string if no parent exists
isa <object>
Test if the object is derived from another one
linkArray ?field? <variable>
Return the name of an array that is linked to the given dictionary-containing field
linkVar ?field? <variable>
Return the name of a variable that is linked to the given field
methods ?name? ?arguments body?
Introspect and create object methods
property <name> <value>
Label the field as a property (bound to local variables when executing this object's methods) for all methods declared after this method is called.
Undo the linking set up with as and return the object
set <field> ?key? <value>
Write an object field
unset <field> ?key?
Destroy an object field

Public helper procedures:
super <method> ?args?
Call method using superclass's definition
new <class> ?args?
Create a new object (based on the given "class" object) and call its constructor with args

The code has a self-test mode too, of course. This currently does some timing tests, and demonstrates the capabilities of the code in relation to error handling, variable linking and delegation.

Provided subclass-like objects are Collection, List, UniqueList, and Map which together form a basic aggregate type framework.

Design Notes

  • The property method acts like the set method except that it also adds the field to the list of fields to be bound to local variables during the body of methods. The methods method uses the current value of this list (which, like almost everything, is inheritable) whenever it creates a method. This means that methods only ever see directly those variables that have been declared with property when they were created; they can only inspect and update variables in subclasses using the get and set methods.
  • The derive method is for creating new classes from existing ones, but any object can act as a class because this is a prototype-based OO scheme. It is the new procedure that really calls the constructor, and the delete method that really calls the destructor.

lv is some background, alternative to the paper, or the paper or powerpoint or something available?

DKF: Not yet. :^)

Look at Conference Slides for pointers.

escargo 11 Dec 2004 - I would find it interesting to see a summary of changes between versions 1, 2, and 3.

DKF: Hmm. These are the main things that I can think of right now... :^)

v1 ¨ 2

Reimplemented virtually from the ground up; switch to using prototypes instead of jury-rigged classes.

v2 ¨ 3

Introduction of the property exposure rule (outlined above) that greatly simplified things internally.

escargo 18 Jun 2007 - With the change in the 8.5 syntax from {expand} to {*} are you planning another code update?

LV Does this differ from tcloo?

DKF: Yes! Totally. TclOO learned many lessons from this (one of which was that classes required C support to get right, and another of which was that speed of dispatch was totally critical) but shares no code.