yao documentation


For years, Tcl lacked of native support for lambda and OO such that there were many do-it-yourself solutions. Because of eias, lambda expressions as well as object instances were realised as procedures with a temporarily used name. This can be regarded as namespace pollution – especially with the aspect that OO is just an add-on for Tcl which is used where appropriate, elsewhere it is preferrable to work more “Tcl-ish”. (If it were else, think of change the language!)

With Tcl 8.5, the new procedure apply does factually what we expect from lambda expressions – with the benefits of speed, but without the drawback of name pollution. The idea of simply use a leading keyword is taken up by Yet Another Object system yao.

Neither procedures nor variables

YAO uses the namespace ::yao for object-related procedures, but an object is neither a proc nor even a variable in its own right, but just a tag like ::yao::dog::15 the internal data of which reside in a certain array, e.g. ::yao::dog::body(::yao::dog::15) and are arranged internally as a dictionary.


Every object operation is done with keyword object which is created by namespace ensemble. If you want that your dog barks, then say:

object msg $snoopy bark woof!

How to ...

To create a class named dog with certain option defaults, say:

object class dog -options {
    -color white

To create a method for class dog, say:

object method dog bark text {
    puts "dog $self barks -- {$text}"

where the variable $self refers to the instance itself. This is important, because every method call must be done via command msg – see below.

To create a constructor which is invoked on object creation, just create a method named constructor with zero arguments. Same rule applies to destructor which is invoked in first line from method destroy (which is generated automatically).

Attention! Avoid using the methods constructor, destructor, destroy manually!

To create an instance of class dog, say:

object new dog -color black/white

This returns the newly created instance tag, e.g. ::yao::dog::15

To create a procedure-local object on var name, say:

object localvarname snoopy dog -color black/white

Variable snoopy is now traced such that on leaving the current procedure, $snoopy’s method destroy is invoked.

To test if an object exists (i.e. not yet destroyed), say:

object exists $snoopy

Retun value is boolean.

To invoke a method, e.g. make $snoopy bark, say:

object msg $snoopy bark woof!

To abbreviate a method call, you can omit subcommand msg as follows:

object $snoopy bark woof!

To speed up method call inside method definitions, omit main command object as follows:

msg $snoopy bark woof!

(From here on, this documentation always uses the abbreviated form of method call.)

To configure an object, say:

object $snoopy configure -color yellow

To get a certain configuration, say:

object $snoopy cget -color

Configuration options are limited by class definition above.

To associate configuration of a certain option with an action, define an appropriate method named configure$optiopn, e.g. as follows:

object method dog configure-color {} {
    set color [msg $self cget -color]
    puts "I have now color $color!"

To set an arbitrary instance-internal variable, use method var:

object $snoopy var owner me

To request the instance-internal variables, say:

object $snoopy var owner

To see names and values of all internal vars, say:

object $snoopy var

Provided you have made a class tail, you can use some of these vars as object component:

object $snoopy var tail [object new tail]

To invoke methods for these components, e.g. make $snoopy’s tail wag, use method component (which is an abbreviation for: get the value, call method on it).

object $snoopy component tail wag

You can delegate a method to a component, e.g. delegate methd wag on class dog to component tail as follows:

object delegate method wag dog tail

(This is just an abbreviation for writing an appropriate method).

You can delegate an option to a component, e.g. delegate option -color on on class dog to component tail as follows:

object delegate option -color dog tail

(This is just an abbreviation for writing a configure-color handler).

That’s it, folks!