# OTcl Classes (Version 0.96, September 95)

## Overview

This reference page describes the functionality provided for all classes by methods on the `Class` class. See the tutorial for an introduction to programming in OTcl, and the C API page for details of manipulating classes from C.

Classes in OTcl are a special kind of object used mainly for inheritance. By convention, they are named with mixed case to distinguish them from regular objects. They inherit all the abilities of regular objects from `Object`, and add more. The inherited behavior includes method lookup, dispatch, and combination, and initialization syntax. See Objects in OTcl to understand these abilities of regular objects.

Classes are created through meta-class objects, either implicitly with a widget command syntax, or explicitly by calling a creation method. Generic classes may be created with the `Class` class. By default, they will inherit from `Object`. The classes Bagel, and SuperBagel, which inherits from Bagel, may be defined as follows. See the `create` instproc for a description of the overall creation process and how to customize it.

>     % Class Bagel
>     Bagel
>     % Bagel info class
>     Class
>     % Bagel info superclass
>     Object
>     % Class SuperBagel -superclass Bagel
>     SuperBagel
>     % SuperBagel info class
>     Class
>     % SuperBagel info superclass
>     Bagel

`Class` is the repository for the behavior common to all classes. It includes methods for defining new methods for use by instances, initializing and destroying classes, specifying their superclasses, querying them, and so forth. The remainder of this reference page describes these methods. Their functionality can be customized for particular meta-classes or classes by using the standard inheritance mechanisms, or changed directly for all classes by rewriting the methods on `Class` in Tcl or C.

## Alloc

The `alloc` proc is used to allocate a fresh class object that is an instance of class `Class` and has superclass `Object`. It is normally called by the system as part of class creation, but may be called by the user.

The system `create` instproc on `Class` expects all `alloc` procs to take the name of the object to allocate, and a list of arguments. It expects them to allocate the object, install it in the interpreter, and return the list of unprocessed arguments. For the case of the `Class` `alloc` proc, no additional arguments are processed, and so they are all returned.

To customize class creation, write an `init` instproc, not an `alloc` proc. New `alloc` procs will typically be written in C to allocate structurally different types of object.

>     % Class alloc foo bar baz
>     bar baz
>     % foo info class
>     Class
>     % foo info procs
>     % foo info vars

## Create

The `create` instproc provides a mechanism for classes to create other classes and objects. It is invoked by the default `unknown` instproc if no matching method name can be found, and so may be ellided to yield the familiar widget-like creation syntax.

`create` takes the name of a class or object to create plus extra initialization argument pairs, and returns the name of the object or class created. It effectively calls an `alloc` proc to allocate the object, then dispatches the `init` method with the initialization arguments to initialize the object. Recall that the base `init` method on `Object` interprets these arguments as option key and option value pairs, evaluating each pair in turn. The following three sequences are essentially equivalent (except in terms of return value).

>     % Class create Bagel
>     Bagel

>     % Class Bagel
>     Bagel

>     % Class alloc Bagel
>     % Bagel init

The `alloc` proc that is called by create is determined by the class object on which it is called. `create` first looks for an `alloc` proc on this class object, then on its superclasses according to the precedence ordering. The result is that calling `create` on `Class` (or a class specialized from it) will create a new class, whereas calling `create` on `Object` (or a class specialized from it) will create a new object.

Classes may customize the initialization of their instances by defining an `init` instproc. If the option key and option value creation syntax is still desired, this `init` instproc should combine its behavior with the `init` instproc on `Object` by using the `next` instproc, as shown below. For example, the class Bagel may require an instance variable called bites to be initialized to a default value of 12, in addition to regular option key and option value initialization. This is accomplished as follows. (The use of eval is simply to flatten the list of arguments contained in args.) Similarly, an `init` instproc on `Class` may be used to customize the initialization of all classes.

>     % Class Bagel
>     Bagel
>     % Bagel instproc init {args} {
>       $self set bites 12
>       eval $self next $args
>     }
>     % Bagel instproc flavor {f} {
>       $self set flavor $f
>     }
>     % Bagel abagel -flavor sesame
>     abagel
>     % abagel set bites
>     12
>     % abagel set flavor
>     sesame

Alternatively, the standard inheritance mechanisms may be used to provide some or all classes with their own `create` proc, allowing complete control over the creation process. For reference, the default `create` instproc on `Class` is conceptually defined as follows.

>     Class instproc create {obj args} {
>       set h [$self info heritage]
>       foreach i [concat $self $h] {
>         if {[$i info commands alloc] != {}} then {
>           set args [eval [list $i] alloc [list $obj] $args]
>           $obj class $self
>           eval [list $obj] init $args
>           return $obj
>         }
>       }
>       error {No reachable alloc}
>     }

## Info

The `info` instproc is used to query the class and retrieve information about its current state. It mirrors the Tcl info command, and has the following options in addition to those of the `Object` `info` instproc.

- `superclass` returns the superclass list of the object. With an additional argument that is the name of a class, it returns 1 if that class is a direct or indirect superclass of the class, and 0 otherwise.
- `subclass` returns the subclass list of the object. With an additional argument that is the name of a class, it returns 1 if that class is a direct or indirect subclass of the class, and 0 otherwise.
- `heritage` returns the inheritance precedence list (as described for the `superclass` instproc). An additional argument is taken to be a string match pattern which filters the result list.
- `instances` returns a list of the instance objects of the class. An additional argument is taken to be a string match pattern which filters the result list.
- `instprocs` returns a list of the names of instproc methods defined on the class. An additional argument is taken to be a string match pattern which filters the result list.
- `instcommands` returns a list of the names of both Tcl and C instproc methods defined on the class. An additional argument is taken to be a string match pattern which filters the result list.
- `instargs` is used to query the argument list of a Tcl instproc method. It functions in the same manner as the Tcl info args command.
- `instbody` is used to query the body of a Tcl instproc method. It functions in the same manner as the Tcl info body command.
- `instdefault` is used to query the default value of an argument of a Tcl instproc method. It functions in the same manner as the Tcl info default command.

These options can recover most information about the state of a class. As an example, the following instproc returns a list of all direct and indirect instances of a class.

>     Class instproc instances {} {
>       set il {}
>       foreach i [Class info instances] {
>         if {[$self info subclass $i]} then {
>           eval lappend il [$i info instances]
>         }
>       }
>       return $il
>     }

## Instproc

The `instproc` instproc is used to install instproc methods on a class, for use by that class's direct and indirect instances. Use `instproc` to share and inherit behaviors. With particular argument forms, `instproc` can also remove instproc methods from a class, or specify an autoload script for demand loading of the instproc method.

The arguments and body of an instproc method are of the same form as a Tcl procedure, with two exceptions. If both args and body are empty, then an existing instproc method with the specified name is removed from the class. If args is `{auto}`, then the body is interpreted as an autoload script in the same manner as described under the `proc` instproc in OTcl Objects. See OTcl Autoloading for a higher level demand loading scheme.

The following example demonstrates defining instprocs, using them on behalf of and object, and combining their functionality with next.

>     % Class Bagel
>     Bagel
>     % Class SuperBagel -superclass Bagel
>     SuperBagel
>     % Bagel instproc taste {} {
>       puts yum!
>     }
>     % SuperBagel instproc taste {} {
>       $self next
>       puts YUM!
>     }
>     % SuperBagel abagel
>     abagel
>     % abagel taste
>     yum!
>     YUM!

The environment in effect when an instproc is being executed is the same as when a proc is being executed, and is described under the `proc` instproc in OTcl Objects. The special variable `class` may be used for a variety of tasks, such as to access shared variables stored on the class object. For example, the default size of a bagel in bites may be stored on the Bagel class to be accessed during the `init` instproc as follows.

>     % Class Bagel
>     Bagel
>     % Bagel set bites 12
>     12
>     % Bagel instproc init {args} {
>       $class instvar bites
>       $self set size $bites
>       eval $self next $args
>     }
>     % Bagel abagel
>     abagel
>     % abagel set size
>     12
>     % Bagel set bites 7
>     7
>     % Bagel abagel
>     abagel
>     % abagel set size
>     7

## Superclass

The `superclass` instproc is used to change the superclasses from which a class directly inherits behavior. It takes one argument that is a list of superclasses and returns the empty string. The order of the superclass list determines the order of inheritance. Multiple inheritance is supported.

The superclasses must be in precedence order (from most specialized to least specialized) if they are related, and the resulting superclass relation must be cycle-free. An error is returned and the superclass graph is unchanged if either of these conditions are unmet.

The linear precedence order in which superclasses are searched for instprocs is constrained according to each local superclass list. It is guaranteed that if A inherits from B and C, then A will behave like a B before it behaves like a C, and so forth for B and C and their superclasses. The algorithm used to generate this ordering is an unspecified CLOS-like topological sort of the inheritance graph. (This is all you need to know. Multiple inheritance is best thought of in terms of local orderings. If you are relying on subtleties of the global ordering, then you are asking for trouble.)

The `heritage` option of the `info` instproc may be used to discover the precedence order, and hence the path that the `next` instproc will use when instructed to combine methods.

## Unknown

The `unknown` instproc for classes is used to implement implicit creation of objects. It is invoked when no matching method is found, and interprets the method name as the name of an object to be created with `create`, thus allowing a widget-like creation syntax.

See the entry for `unknown` in OTcl Objects for a general description of the unknown method mechanism.

The `unknown` instproc on `Class` is conceptually defined as follows. It you do not want implicit creation, then redefine or remove the default method with the `instproc` method.

>     Class instproc unknown {m args} {
>       if {$m == {create}} then {
>         error "$self: unable to dispatch $m"
>       }
>       eval [list $self] create [list $m] $args
>     }