class Toaster { variable crumbs 0 method toast {nslices} { if {$crumbs > 50} { error "== FIRE! FIRE! ==" } set crumbs [expr $crumbs+4*$nslices] } method clean {} { set crumbs 0 } }In Things, ways ("methods") are defined outside the "class" declaration, so you can add ways and properties ("variables" - just by setting them) at any time, while in Itcl a class (including its methods and variables) can only be defined once. In exchange, accessing a thing's variables requires referring to self:
thing new Toaster crumbs 0 Toaster wayto toast {{self nslices} { if {[$self crumbs]>50} { error "$self:=== FIRE! FIRE! ===" } $self set crumbs [expr [$self crumbs]+4*$nslices] } } Toaster wayto clean {{self} {$self set crumbs 0}}Next comes a smart toaster, that acts like a normal one except that it cleans itself if the crumb count gets dangerously high. Itcl:
class SmartToaster { inherit Toaster method toast {nslices} { if {$crumbs > 40} { clean } return [Toaster::toast $nslices] # alternatively: return [chain $nslices] } }Things (I still have to think on how to emulate the chain command):
Toaster new SmartToaster ;# inheritor in front SmartToaster wayto toast {{self nslices} { if {[$self crumbs]>40} { $self clean } ::thing::Toaster::toast $self $nslices } } SmartToaster new T1 ;# create an "object" with the 'new' way T1 toast 3 ;#...Pretty similar at first glance, and in operation, Toasters and SmartToasters behave like I'd expect them to (and both Itcl's and Things' SmartToasters may burn if you toast more than three slices in one go...). But what I like most about those Things: it took 2 pages of Tcl code (see Doing things in namespaces) to get'em going ...;-)
A modified version (see Chaining things) allows chaining, in the form
SmartToaster wayto toast {{self nslices} { if {[$self crumbs]>40} { $self clean } ::thing::chain $nslices } }
SS 9Apr2005: what about a more smalltalkish solution where every thing has a parent method, so that instead of:
::thing::chain $nslicesit is possible to write
$self parent toast $nslices?RS Makes sense - except that mentioning the name of a method inside its body is a bit risky if you change the name outside but not inside.