Poet2.2 Manual Prototype Object Extension for Tcl


Poet objects can be made persistent by mixing in the object Thing. To configure persistence, use the object ThingPool, where a pool is a repository for persistent objects. A Poet pool may be either a file or a directory. If it's a directory, each descendant of Thing is written out as a Tcl script consisting of the commands that will recreate the object by constructing it, setting all of its public slots, and declaring all of its methods, formulas, and types. If the pool is a file, it will be written using Metakit's Virtual File System.

Here is an example of how to set up for persistence, using the first command-line argument to the program as the name of the pool (either a file or directory).
ThingPool setFile [lindex $::argv 0]
ThingPool slot writable 1

rename exit crash
proc exit {{returnCode 0}} {
ThingPool slot
crash $returnCode

ThingPool open

The first two lines set the pool filename and make it writable. We then redefine exit so that the pool will be closed when the application exits. Finally, we open the pool.

Note that all Things must have unique names. If you want to use anonymous names, you should provide a prefix ending with '@' when constructing the object. One handy approach is to define a method called new that calls construct correctly, and use it instead. Here's an example of a persistent object with anonymous persistent children:
Object construct Employee
Employee mixin Thing

Employee slot name ""
Employee slot dateOfHire ""
Employee slot salary ""

Employee method new {} {
return [$self construct employee@]

Things are autoloaded from the persistent storage as they are referenced. Use ThingPool load pattern to manually load a set of objects, all the objects whose names match (using string match) the pattern are loaded. If the pattern is not provided, it defaults to *@*, which should load all the anonymous persistent objects.

If you have a tree-like structure that persists, it may be sufficient to load just the root and let the nodes get loaded as they are referenced. If you want to load the tree and all its descendants, override the method Thing Thing_postload. This method gets called on a Thing when it is autoloaded, and can be used to load the children (or anything else you want your objects to do when they're loaded). Make sure you invoke Thing Thing_postload in your overriding method, it keeps track of a counter of how many objects have been loaded.