XOTcl Introductory Example was posted by Gustaf Neumann GN to comp.lang.tcl
XOTcl supports open class definitions, object specific behavior and mixin classes (among other things) to achieve dynamic behavior extensions. The so-called per-object mixins are actually an implementation of the decorator pattern that Bob mentions.
The following example is modelled to express the intentions from the examples earlier in this thread.
hope, you find it interesting
best regards
-gustaf
# Here is the original example: a method from a derived class # extends the behavior of the baseclass; the primitive "next" # calls other same-named methods. In the example below, the # baseclass method "speak" is called at the beginning of the # derived-class method. The primitive "next" can be placed at # arbitrary places, or it can be omitted when the baseclass method # should not be called. Class BaseClass BaseClass instproc speak {} { puts "Hello from BC." } Class DerivedClass -superclass BaseClass DerivedClass instproc speak {} { next puts "Hello from DC." } DerivedClass create o1 o1 speak # The output is: # Hello from BC. # Hello from DC. # There are many ways to extend the behavior XOTcl classes # at runtime. The easiest thing is to add methods dynamically # to classes. E.g. we can extend the BaseClass with the method # unknown, which is called whenever an unknown method is called. BaseClass instproc unknown {m args} { puts "What? $m? I don't understand." } o1 sing # The output is: # What? sing? I don't understand. # Often, you do not want to extend the class, but to # modifiy the behavior of a single object. In XOTcl, an object # can have individual methods: o1 proc sing {} { puts "Ok, here it goes: Lala Lala!" } o1 sing # The output is: # Ok, here it goes: Lala Lala! # In many situations, it is desired to add/remove a set # of methods dynamically to objects or classes. The mechanisms # above allow this, but they are rather cumbersome and do # support a systematic behavior engineering. One can add # so-called "mixin classes" to objects and/or classes. For # example, we can define a class M for a more verbose methds: Class M M instproc sing {} { puts -nonewline "[self] sings: " next } M instproc unknown args { puts -nonewline "[self] is confused: " next } # The behavior of M can be mixed into the beavior of o1 through # per object mixins ... o1 mixin M # ... and we call the methods again: o1 sing o1 read # The output is: # ::o1 sings: Ok, here it goes: Lala Lala! # ::o1 is confused: What? read? I don't understand. # We can remove the new behavior easily by unregistering the # mixin class .... o1 mixin "" # ... and we call the methods again: o1 sing o1 read # The output is: # Ok, here it goes: Lala Lala! # What? read? I don't understand. # Mixin classes can be used to extend the behavior of classes # as well. BaseClass instmixin M o1 sing o1 read DerivedClass create o2 o2 read # The output is: # ::o1 sings: Ok, here it goes: Lala Lala! # ::o1 is confused: What? read? I don't understand. # ::o2 is confused: What? read? I don't understand.