Further, there are activities such as object-oriented analysis (OOA) and object-oriented design (OOD) that concern themselves with analyzing a system (or a solution to a problem) in terms of objects and their behaviors.
"An object or two may sometimes be nice, just like a glass of beer. But one shouldn't start drinking at breakfast." (RS)
RS In a smokebreak, I whipped up this hierarchy of things, by weight:
- 1. process
- 2. thread
- 3. interp
- 4. namespace
- 5. commands, persistent vars
- 6. local vars
- 7. values (TclObjs) - strings, lists, dicts, ...
Another shade of meaning for OO is
What: OO Where: http://www.cs.umn.edu/%7Edejong/tcl/OO.zip Description: OO extension that works in Tcl 7, Tcl 8, and Jacl. Updated: 08/1998 Contact: mailto:dejong at cs.umn.edu
As RS aptly observes in "interp alias", object methods can be described as syntactic sugar for a certain form of dispatching. - RS 2005-03-27: I'd even go further and say that quite a bunch of what is called OO can be done in pure Tcl without a "framework", only that the code might look clumsy and distracting. Just choose how to implement instance variables:
- in global variables or namespaces
- or in closures, e.g. with Jim
- or just as parts of a transparent value, with TOOT
namespace eval Stack {set n 0}
proc Stack::Stack {} { #-- construktor
variable n
set instance [namespace current]::[incr n]
namespace eval $instance {variable s {}}
interp alias {} $instance {} ::Stack::do $instance ;# $object method arg.. sugar
}
proc Stack::do {self method args} { #-- Dispatcher with methods
upvar #0 ${self}::s s
switch -- $method {
push {eval lappend s $args}
pop {
if ![llength $s] {error "stack underflow"}
K [lindex $s end] [set s [lrange $s 0 end-1]]
}
default {error "unknown method $method"}
}
}
proc K {a b} {set a}Other examples for this framework-less "bare-bone OO" are at Skeleton OO, A little IO stack, Tiny OO with Jim, and Jim closures. A framework would just have to make sure that the above code is functionally equivalent to, e.g. (in a fantasy OO style): class Stack {
variable s {}
method push args {eval lappend s $args}
method pop {} {
if ![llength $s] {error "stack underflow"}
K [lindex $s end] [set s [lrange $s 0 end-1]]
}
}which, I admit, reads definitely better. But bare-bones has its advantages too: in order to see how a clockwork works, you'd better have all parts visible :)