Migrating between XOTcl and TclOO

This page describes how to migrate between XOTcl and TclOO. The direction is not important because there are good arguments to use both object-oriented frameworks like supported tcl versions, speed or availability in tcl core.

By programming xotcl-light I have fronted some discrepancies in function or even quite different meaning. Although TclOO seems to be quite influenced by XOTcl, it was changed.

If you want to run XOTcl code without XOTcl extension try xotcl-light

next command

  • XOTcl supports next command without arguments, which is shortcut for just passing all arguments
  • In XOTcl next will be just ignored if there is no parent implementation; in TclOO it will lead to error message (unknown command)

name and namespace

TclOO distinguishes between name and namespace. For XOTcl, it is the same, but XOTcl will not create the namespace at once (for performance reasons); you need to call requireNamespace.

In TclOO you need to be careful about it. It could be that name and namespace are the same but not always. For objects created per new name and namespace are same. By objects created per create they are different.

oo::class create A {
   method getName {} {
       self object
   }
}

set o1 [A new]
set o2 [A create mya]

info object namespace $o1
$o1 getName
info object namespace $o2
$o2 getName # we get ::mya

creating namespace for XOTcl object

$obj requireNamespace

nesting objects

XOTcl supports so-called nested objects. It is very useful to manage object lifetime (! there is no garbage collection in both oo extensions)

Class create A
set a [A new]
set child [A new -childof $a]
$a info children
$child info parent
$a destroy
# $child is also destroyed

In TclOO this can be simulated by using unexported method cls createWithNamespace name nsName ?arg ...?

oo::class create A {
    self method createChildOf {object name args} {
        set ns [info object namespace $object]::$name
        my createWithNamespace $ns $ns {*}$args
    }
}
set a [A new]
set child [A createChildOf $a child]
$a destroy

instvar and variable

This method holds the instance variable into method context. The TclOO variable accepts only one argument.

XOTcl parameters

XOTcl support shortcuts for parameter

Class A -parameter p
set a [A new -p v1]
$a p
$a p 23

This can be easy simulated in TclOO by using some generic getter and setter and forward. passing -{name} is constructor to {name} method is some trick but maybe not the best XOTcl idea, because some other problems with it.

oo::class create A {
    method parHandler {parName args} {
        my variable $parName
        set $parName {*}$args
    }
    method createParameter par {
        oo::objdefine [self] forward $par [self] parHandler $par
    }
}
set a [A new]
$a createParameter p
$a p 2
$a p

getting full object name

In XOTcl you may always call the method without any argument on object name to get its full name (it is same as self call); in TclOO you may need to use namespace command or self object (which can be abbreviated to self).

XOTcl

Class A
namespace eval myns {
    A create mya
    set fullName [mya]
}

TclOO

oo::class create A {
   method getName {} {
       self
   }
}
namespace eval myns {
    A create mya
    set fullName [mya getName]
    # or standard tcl way
    set fullName [namespace which mya]
}

XOTcl -volatile

XOTcl has quite useful option that allows to limit the lifetime of object to scope of procedure, in which the object was created. It is similar to ITcl itcl::local

XOTcl

Class A
proc foo {} {
   set a [A new -volatile]
   # object will be destroyed after the end of procedure
}
foo

In TclOO this functionality can be simulated by using the variable unset trace. See implementation in xotcl-light or the implementation of itcl::local in Tcl 8.6.