C/Tcl Interface - Hierarchical Objects
In Janus you can use a dot or a colon to descend in an object hierarchy. For example
ob1.ob2:ob3.ob4:ob5:ob6 refers to an object ob6 which is a subobject of
an object ob5, which itself is a subobject of ... etc.
The colon is used to descend into a list element that is referenced by name. In the above
example cb3, cb5 and cb6 are names of list elements, and ob2
and ob4 are singular subobjects objects (like structure fields in C).
Examples:
Imagine you have a distributions set (DistribSet) object, named dss. Every distribution set
object must have exactly one codebook set (CodebookSetCodebookSet is
named cbs, then the distribution set was most likely created with the command DistribSet dss cbs.
Now you can access the codebook set in two ways, first you can simply use the name cbs, and the second
option is the name dss.codebookSet. Here the dot means, "Give me the codebook of the distribution
set dss.
A distribution set usually has some distributions (Distrib) as its subobjects. These are stored in a
generic list. Each distribution has a name, and can be acessed using the colon construct. Say, you want to access
the distribution named SIL-m(0) of the distribution set dss then you can type dss:SIL-m(0).
Here you don't have the alternative to access the single distribution directly, because it only exists within the
senone set object. If you don't know the name of the distribution which you want to access, but you do know its
index, say 123, (e.g. from the configuration output of a senone), then you can also access it by dss.item(123).
You can use colon or dot constructs wherever an existing object is expected. You can run methods for hierarchically
named objects and you can use them as arguments for methods and procedures that expect an object.
Theoretically, there is no limit to the nesting depth. You could, for example, do:
dss.codebookSet.featureSet:LDA.data
for accessing the matrix of the LDA feature of the feature set of the
codebook set of the distribution set dss.
How Is It Done
Every implementation of an object class that can have subobjects should have an access function in its type information
structure. Whenever the interface module has to analyse a hierarchical object it parses the name til the next colon or
dot, finds out what object type the first name belongs to, calls this object class's access function with the next
name in the hierarchy, receiving a pointer to the subobject and a pointer to the subobject's type information structure.
Every descend step is stored, such that C function that need to know not only a pointer to the object on which they
should work, but also its full name as entered by the user, can access that full name by calling itfCommandName(),
a string-valued parameterless function in the interface module.