TAO

The TCL Architecture of Objects

Not to be confused with Tao (S), the ever changing state of the Universe, The Tao of Tcl, or The Ace Orb (TAO) [L1 ], which uses a feather icon on their web site.

Quick Links

Pre-Requisits

The Tao core assumes the presence of sqlite3. Higher level portions of the API make calls to modules of odielib, tcllib, and tklib.

Tao Modules

  • tao - The main parser and core classes
  • taotk - A megawidget system based on Tao objects
  • tao-sqlite - A mega-object system based on Sqlite data containers

Introduction to TAO Programming

Tao is language extension to TclOO. All Tao code is inheritable by TclOO and any TclOO class can be inherited by Tao. The rules of TAO are designed to make behavior predictable for very large, complex, and otherwise nasty class hierarchies. TclOO code can be fed, without only slight modification, into the Tao.

Tao adds the following features to TclOO Objects:

  • properties - Data that propagates the same way as code throughout your class hierarchies
  • option handling - Built in tk-style option handling. (Even for non tk-objects)
  • ensemble methods - A language convention that allows complex method to be broken up into ensembles and be implemented piecewise.
  • sqlite introspection - Data for Tao is tracked using an sqlite backend
  • class methods - Methods that apply to the class, and not the objects of the class.
  • message passing - Tao provides an sqlite-based mechanism for inter-object communication
  • organ-i-zation - Tao adds the concept of "organs" or "pointers" to facilitate breaking complex jobs into multiple object.

A typical class looks something like this:

###
# Someone who potentially owns a towel
###
tao::define owner {
  variable inventory {}

  ###
  # An ensemble that implements "inventory"
  ###
  method inventory::add {type object} { 
    my variable inventory
    dict lappend inventory $type $object
  }
  method inventory::remove {type object} { 
    my variable inventory
    set list [my inventory list $type]
    ldelete list $object
    dict set inventory $type $list
  }
  method inventory::list {type} { 
    my variable inventory
    if {[dict exists $inventory $type]} { 
      return [dict get $inventory $type]
    }
    return {}
  }

  ###
  # an extension to the "is" ensemble which defines
  # the state of hoopy as knowing where one's towel is
  # namely by having it on one's person
  ###
  method is::hoopy {} { 
     my variable in
     foreach towel [my inventory list towel] {
        if { [$towel location] eq [my location] } } {
           return 1
        }
     }
     return 0
  }
}
  
###
# Something owned by someone who potentially owns a towel
###
tao::define towel {
  # List other names this towel could be addressed as
  aliases dishtowel bathtowel beachtowel

  superclass linen

  option owner {default nobody}

  method initialize {} { 
    if {[my organ owner] ne "nobody"} { 
      my Newowner [my cget owner]
    }
  }
 
  ###
  # Show off grafting. When we get a new owner
  # we link ourselves to the new owner AND we 
  # create a link that allows us to access the owner object
  # as a public method "owner" or private method "<owner>"
  ###
  method Newowner newowner {
     if {[my organ owner] ni {nobody {}}} { 
        my <owner> inventory remove towel [self]
     }
     my graft owner $newowner
     my <owner> inventory add towel [self]
   }
}

owner create FordPrefect
FordPrefect is froody
> 0
towel new {owner FordPrefect}
FordPrefect is froody
> 1