itcl User Commands - class
NAME
class - create a class of objects
SYNOPSIS
class className {
inherit baseClass ?baseClass...?
constructor args ?init? body
destructor body
method name ?args? ?body?
proc name ?args? ?body?
variable varName ?init? ?config?
common varName ?init?
public command ?arg arg ...?
protected command ?arg arg ...?
private command ?arg arg ...?
set varName ?value?
array option ?arg arg ...?
}
className objName ?arg arg ...?
objName method ?arg arg ...?
className::proc ?arg arg ...?
DESCRIPTION
The fundamental construct in [incr Tcl] is the class defini-
tion. Each class acts as a template for actual objects that
can be created. The class itself is a namespace which con-
tains things common to all objects. Each object has its own
unique bundle of data which contains instances of the "vari-
ables" defined in the class definition. Each object also
has a built-in variable named "this", which contains the
name of the object. Classes can also have "common" data
members that are shared by all objects in a class.
Two types of functions can be included in the class defini-
tion. "Methods" are functions which operate on a specific
object, and therefore have access to both "variables" and
"common" data members. "Procs" are ordinary procedures in
the class namespace, and only have access to "common" data
members.
If the body of any method or proc starts with "@", it is
treated as the symbolic name for a C procedure. Otherwise,
it is treated as a Tcl code script. See below for details
on registering and using C procedures.
A class can only be defined once, although the bodies of
class methods and procs can be defined again and again for
interactive debugging. See the body and configbody commands
for details.
Each namespace can have its own collection of objects and
classes. The list of classes available in the current con-
text can be queried using the "info classes" command, and
the list of objects, with the "info objects" command.
A class can be deleted using the "delete class" command.
Individual objects can be deleted using the "delete object"
command.
CLASS DEFINITIONS
class className definition
Provides the definition for a class named className.
If the class className already exists, or if a command
called className exists in the current namespace con-
text, this command returns an error. If the class
definition is successfully parsed, className becomes a
command in the current context, handling the creation
of objects for this class.
The class definition is evaluated as a series of Tcl state-
ments that define elements within the class. The following
class definition commands are recognized:
inherit baseClass ?baseClass...?
Causes the current class to inherit characteris-
tics from one or more base classes. Classes must
have been defined by a previous class command, or
must be available to the auto-loading facility
(see "AUTO-LOADING" below). A single class defin-
ition can contain no more than one inherit com-
mand.
The order of baseClass names in the inherit list
affects the name resolution for class members.
When the same member name appears in two or more
base classes, the base class that appears first in
the inherit list takes precedence. For example,
if classes "Foo" and "Bar" both contain the member
"x", and if another class has the "inherit" state-
ment:
inherit Foo Bar
then the name "x" means "Foo::x". Other inherited
members named "x" must be referenced with their
explicit name, like "Bar::x".
constructor args ?init? body
Declares the args argument list and body used for
the constructor, which is automatically invoked
whenever an object is created.
Before the body is executed, the optional init
statement is used to invoke any base class con-
structors that require arguments. Variables in
the args specification can be accessed in the init
code fragment, and passed to base class construc-
tors. After evaluating the init statement, any
base class constructors that have not been exe-
cuted are invoked automatically without arguments.
This ensures that all base classes are fully con-
structed before the constructor body is executed.
By default, this scheme causes constructors to be
invoked in order from least- to most-specific.
This is exactly the opposite of the order that
classes are reported by the info heritage command.
If construction is successful, the constructor
always returns the object name-regardless of how
the body is defined-and the object name becomes a
command in the current namespace context. If con-
struction fails, an error message is returned.
destructor body
Declares the body used for the destructor, which
is automatically invoked when an object is
deleted. If the destructor is successful, the
object data is destroyed and the object name is
removed as a command from the interpreter. If
destruction fails, an error message is returned
and the object remains.
When an object is destroyed, all destructors in
its class hierarchy are invoked in order from
most- to least-specific. This is the order that
the classes are reported by the "info heritage"
command, and it is exactly the opposite of the
default constructor order.
method name ?args? ?body?
Declares a method called name. When the method
body is executed, it will have automatic access to
object-specific variables and common data members.
If the args list is specified, it establishes the
usage information for this method. The body
command can be used to redefine the method body,
but the args list must match this specification.
Within the body of another class method, a method
can be invoked like any other command-simply by
using its name. Outside of the class context, the
method name must be prefaced an object name, which
provides the context for the data that it manipu-
lates. Methods in a base class that are redefined
in the current class, or hidden by another base
class, can be qualified using the
"className::method" syntax.
proc name ?args? ?body?
Declares a proc called name. A proc is an ordi-
nary procedure within the class namespace. Unlike
a method, a proc is invoked without referring to a
specific object. When the proc body is executed,
it will have automatic access only to common data
members.
If the args list is specified, it establishes the
usage information for this proc. The body command
can be used to redefine the proc body, but the
args list must match this specification.
Within the body of another class method or proc, a
proc can be invoked like any other command-simply
by using its name. In any other namespace con-
text, the proc is invoked using a qualified name
like "className::proc". Procs in a base class
that are redefined in the current class, or hidden
by another base class, can also be accessed via
their qualified name.
variable varName ?init? ?config?
Defines an object-specific variable named varName.
All object-specific variables are automatically
available in class methods. They need not be
declared with anything like the global command.
If the optional init string is specified, it is
used as the initial value of the variable when a
new object is created. Initialization forces the
variable to be a simple scalar value; uninitial-
ized variables, on the other hand, can be set
within the constructor and used as arrays.
The optional config script is only allowed for
public variables. If specified, this code frag-
ment is executed whenever a public variable is
modified by the built-in "configure" method. The
config script can also be specified outside of the
class definition using the configbody command.
common varName ?init?
Declares a common variable named varName. Common
variables reside in the class namespace and are
shared by all objects belonging to the class.
They are just like global variables, except that
they need not be declared with the usual global
command. They are automatically visible in all
class methods and procs.
If the optional init string is specified, it is
used as the initial value of the variable. Ini-
tialization forces the variable to be a simple
scalar value; uninitialized variables, on the
other hand, can be set with subsequent set and
array commands and used as arrays.
Once a common data member has been defined, it can
be set using set and array commands within the
class definition. This allows common data members
to be initialized as arrays. For example:
class Foo {
common boolean
set boolean(true) 1
set boolean(false) 0
}
Note that if common data members are initialized
within the constructor, they get initialized again
and again whenever new objects are created.
public command ?arg arg ...?
protected command ?arg arg ...?
private command ?arg arg ...?
These commands are used to set the protection
level for class members that are created when com-
mand is evaluated. The command is usually method,
proc, variable orcommon, and the remaining arg's
complete the member definition. However, command
can also be a script containing many different
member definitions, and the protection level will
apply to all of the members that are created.
CLASS USAGE
Once a class has been defined, the class name can be used as
a command to create new objects belonging to the class.
className objName ?args...?
Creates a new object in class className with the name
objName. Remaining arguments are passed to the con-
structor of the most-specific class. This in turn
passes arguments to base class constructors before
invoking its own body of commands. If construction is
successful, a command called objName is created in the
current namespace context, and objName is returned as
the result of this operation. If an error is encoun-
tered during construction, the destructors are automat-
ically invoked to free any resources that have been
allocated, the object is deleted, and an error is
returned.
If objName contains the string "#auto", that string is
replaced with an automatically generated name. Names
have the form className<number>, where the className
part is modified to start with a lowercase letter. In
class "Toaster", for example, the "#auto" specification
would produce names like toaster0, toaster1, etc. Note
that "#auto" can be also be buried within an object
name:
fileselectiondialog .foo.bar.#auto -background red
This would generate an object named
".foo.bar.fileselectiondialog0".
OBJECT USAGE
Once an object has been created, the object name can be used
as a command to invoke methods that operate on the object.
objName method ?args...?
Invokes a method named method on an object named
objName. Remaining arguments are passed to the argu-
ment list for the method. The method name can be "con-
structor", "destructor", any method name appearing in
the class definition, or any of the following built-in
methods.
BUILT-IN METHODS
objName cget option
Provides access to public variables as configuration
options. This mimics the behavior of the usual "cget"
operation for Tk widgets. The option argument is a
string of the form "-varName", and this method returns
the current value of the public variable varName.
objName configure ?option? ?value option value ...?
Provides access to public variables as configuration
options. This mimics the behavior of the usual
"configure" operation for Tk widgets. With no argu-
ments, this method returns a list of lists describing
all of the public variables. Each list has three ele-
ments: the variable name, its initial value and its
current value.
If a single option of the form "-varName" is specified,
then this method returns the information for that one
variable.
Otherwise, the arguments are treated as option/value
pairs assigning new values to public variables. Each
variable is assigned its new value, and if it has any
"config" code associated with it, it is executed in the
context of the class where it was defined. If the
"config" code generates an error, the variable is set
back to its previous value, and the configure method
returns an error.
objName isa className
Returns non-zero if the given className can be found in
the object's heritage, and zero otherwise.
objName info option ?args...?
Returns information related to a particular object
named objName, or to its class definition. The option
parameter includes the following things, as well as the
options recognized by the usual Tcl "info" command:
objName info class
Returns the name of the most-specific class for
object objName.
objName info inherit
Returns the list of base classes as they were
defined in the "inherit" command, or an empty
string if this class has no base classes.
objName info heritage
Returns the current class name and the entire list
of base classes in the order that they are
traversed for member lookup and object destruc-
tion.
name? ?-args? ?-body?
objName info function ?cmdName? ?-protection? ?-
type? ?-
With no arguments, this command returns a list of
all class methods and procs. If cmdName is speci-
fied, it returns information for a specific method
or proc. If no flags are specified, this command
returns a list with the following elements: the
protection level, the type (method/proc), the
qualified name, the argument list and the body.
Flags can be used to request specific elements
from this list.
name? ?-init? ?-value? ?-config?
objName info variable ?varName? ?-protection? ?-
type? ?-
With no arguments, this command returns a list of
all object-specific variables and common data
members. If varName is specified, it returns
information for a specific data member. If no
flags are specified, this command returns a list
with the following elements: the protection
level, the type (variable/common), the qualified
name, the initial value, and the current value.
If varName is a public variable, the "config" code
is included on this list. Flags can be used to
request specific elements from this list.
CHAINING METHODS/PROCS
Sometimes a base class has a method or proc that is rede-
fined with the same name in a derived class. This is a way
of making the derived class handle the same operations as
the base class, but with its own specialized behavior. For
example, suppose we have a Toaster class that looks like
this:
class Toaster {
variable crumbs 0
method toast {nslices} {
if {$crumbs > 50} {
error "== FIRE! FIRE! =="
}
set crumbs [expr $crumbs+4*$nslices]
}
method clean {} {
set crumbs 0
}
}
We might create another class like SmartToaster that rede-
fines the "toast" method. If we want to access the base
class method, we can qualify it with the base class name, to
avoid ambiguity:
class SmartToaster {
inherit Toaster
method toast {nslices} {
if {$crumbs > 40} {
clean
}
return [Toaster::toast $nslices]
}
}
Instead of hard-coding the base class name, we can use the
"chain" command like this:
class SmartToaster {
inherit Toaster
method toast {nslices} {
if {$crumbs > 40} {
clean
}
return [chain $nslices]
}
}
The chain command searches through the class hierarchy for a
slightly more generic (base class) implementation of a
method or proc, and invokes it with the specified arguments.
It starts at the current class context and searches through
base classes in the order that they are reported by the
"info heritage" command. If another implementation is not
found, this command does nothing and returns the null
string.
AUTO-LOADING
Class definitions need not be loaded explicitly; they can be
loaded as needed by the usual Tcl auto-loading facility.
Each directory containing class definition files should have
an accompanying "tclIndex" file. Each line in this file
identifies a Tcl procedure or [incr Tcl] class definition
and the file where the definition can be found.
For example, suppose a directory contains the definitions
for classes "Toaster" and "SmartToaster". Then the "tclIn-
dex" file for this directory would look like:
# Tcl autoload index file, version 2.0 for [incr Tcl]
# This file is generated by the "auto_mkindex" command
# and sourced to set up indexing information for one or
# more commands. Typically each line is a command that
# sets an element in the auto_index array, where the
# element name is the name of a command and the value is
# a script that loads the command.
set auto_index(::Toaster) "source $dir/Toaster.itcl"
set auto_index(::SmartToaster) "source $dir/SmartToaster.itcl"
The auto_mkindex command is used to automatically
generate "tclIndex" files.
The auto-loader must be made aware of this directory by append-
ing the directory name to the "auto_path" variable. When this
is in place, classes will be auto-loaded as needed when used in
an application.
C PROCEDURES
C procedures can be integrated into an [incr Tcl] class
definition to implement methods, procs, and the "config"
code for public variables. Any body that starts with "@" is
treated as the symbolic name for a C procedure.
Symbolic names are established by registering procedures via
Itcl_RegisterC(). This is usually done in the Tcl_AppInit()
procedure, which is automatically called when the inter-
preter starts up. In the following example, the procedure
My_FooCmd() is registered with the symbolic name "foo".
This procedure can be referenced in the body command as
"@foo".
int
Tcl_AppInit(interp)
Tcl_Interp *interp; /* Interpreter for application. */
{
if (Itcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
if (Itcl_RegisterC(interp, "foo", My_FooCmd) != TCL_OK) {
return TCL_ERROR;
}
}
C procedures are implemented just like ordinary Tcl com-
mands. See the CrtCommand man page for details. Within the
procedure, class data members can be accessed like ordinary
variables using Tcl_SetVar(), Tcl_GetVar(), Tcl_TraceVar(),
etc. Class methods and procs can be executed like ordinary
commands using Tcl_Eval(). [incr Tcl] makes this possible
by automatically setting up the context before executing the
C procedure.
This scheme provides a natural migration path for code
development. Classes can be developed quickly using Tcl
code to implement the bodies. An entire application can be
built and tested. When necessary, individual bodies can be
implemented with C code to improve performance.
KEYWORDS
class, object, object-oriented