I spent much of today chasing down an odd behavior with Tao. It passed all of my test scripts, but I ran into the most bizarre malfunction. I have a new behavior for “elements”, when they save the objects mark themselves as “delete me next trashday.”
 
The methods looks like this:
 
    ###
    #  Mark that this object should be deleted
    #  on the next pass of the garbage collector
    #
    #  CAROSEL... RENEW RENEW
    ###
    method carosel {} {
    thanatos kiss $this
    }
 
    ###
    #  Write the contentes of this node to the container's table
    #
    #  This will automatically put the object on the carosel to
    #  be "renewed" on the next pass of the garbage collector
    ###
    method renew {} {
    $containerObj nodeSet $node_id [dict get [set $statevar] state]
    carosel
    }
 
Here’s what happened: instead of the node freeing itself, the CONTAINER freed itself. It took me a bit of coding, tapping out test cases, and whatnot to find that it was a bug in how I was manipulating the stack.
 
  
    proc opop {} {
    variable ostack
    set handle [lindex $ostack 0]
        set ostack [lrange $ostack 1 end]
    set ::tao::topobject $handle
    return $handle
    }
 
Now this HAD worked for all of my test cases. The problem was none of my test cases called out to another object, and then continued on. I finally rewrote the opop proc to:
  
    proc opop {} {
    variable ostack
    set handle [lindex $ostack 0]
        set ostack [lrange $ostack 1 end]
    set ::tao::topobject [lindex $ostack 0]
    return $handle
    }
 
The change is that clobjects now need to push themselves onto the stack. Before they used the ::tao::opoke call to make their presence known to the stack. (Not to mention imprint themselves on the top of every procedure.) As it is, I think the idea of calling a clobjects methods directly will be officially deprecated. From now on, use the ensemble.
 
While I was working on things, I have greatly simplified the structure of Containers, simplified garbage collection, and developed a more formal approach to method naming. “RecordLoad” and “RecordSave” have been replaced by “nodeGet” and “nodeSet”. (Not all nodes are records).
 
I have also GREATLY simplified the process of launching a node from a container. Before it was a hodge-podge of interactions directly between the container and the new node. No more. Now TDIF handles it all. It calls a new chain method “train” in the Container that takes the nodeId for the new node. train returns a dict with a complete configuration of the new object, suitable for passing to ::tao::object_create (i.e. it includes the class).
 
To feed data to child nodes, chain onto train. Remember that there is a variable named “result” that comes with the chain, and it is a dict containing the new state of the object. By default the first thing added to the new -objects dict is the complete memory of what values it holds from the container.
 
 
August 8, 2007
Progress Report - Container Working
Tao Development Blog