class (n) - Linux Manuals
class: create a class of objects
NAME
class - create a class of objects
SYNOPSIS
itcl::class className {
className objName ?arg arg ...?
objName method ?arg arg ...?
className::proc ?arg arg ...?
The fundamental construct in [incr Tcl] is the class definition.
Each class acts as a template for actual objects that can be created.
The class itself is a namespace which contains things common to all
objects. Each object has its own unique bundle of data which contains
instances of the "variables" 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 definition.
"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 context can be queried
using the "itcl::find classes" command, and the list of objects,
with the "itcl::find objects" command.
A class can be deleted using the "delete class" command.
Individual objects can be deleted using the "delete object"
command.
The class definition is evaluated as a series of Tcl
statements that define elements within the class. The following
class definition commands are recognized:
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" statement:
Before the body is executed, the
optional init statement is used to invoke any base class
constructors that require arguments. Variables in the args
specification can be accessed in the init code fragment,
and passed to base class constructors. After evaluating the
init statement, any base class constructors that have
not been executed are invoked automatically without arguments.
This ensures that all base classes are fully constructed 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 construction fails, an error message is returned.
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.
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 manipulates.
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.
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 context, 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.
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; uninitialized 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 fragment 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.
If the optional init string is specified, it is used as the
initial value of the variable. Initialization 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:
Once a class has been defined, the class name can be used as a
command to create new objects belonging to the class.
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:
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.
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 "tclIndex" file for this
directory would look like:
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 interpreter 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".
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.
}
DESCRIPTION
CLASS DEFINITIONS
then the name "x" means "Foo::x". Other inherited members named
"x" must be referenced with their explicit name, like "Bar::x".
inherit Foo Bar
Note that if common data members are initialized within the
constructor, they get initialized again and again whenever new
objects are created.
itcl::class Foo {
common boolean
set boolean(true) 1
set boolean(false) 0
}
CLASS USAGE
This would generate an object named ".foo.bar.fileselectiondialog0".
fileselectiondialog .foo.bar.#auto -background red
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.
BUILT-IN METHODS
CHAINING METHODS/PROCS
Sometimes a base class has a method or proc that is redefined 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:
We might create another class like SmartToaster that redefines
the "toast" method. If we want to access the base class method,
we can qualify it with the base class name, to avoid ambiguity:
itcl::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
}
}
Instead of hard-coding the base class name, we can use the
"chain" command like this:
itcl::class SmartToaster {
inherit Toaster
method toast {nslices} {
if {$crumbs > 40} {
clean
}
return [Toaster::toast $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.
itcl::class SmartToaster {
inherit Toaster
method toast {nslices} {
if {$crumbs > 40} {
clean
}
return [chain $nslices]
}
}
AUTO-LOADING
The auto-loader must be made aware of this directory by appending
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.
# 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.
C PROCEDURES
C procedures are implemented just like ordinary Tcl commands.
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.
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;
}
}
KEYWORDS
class, object, object-oriented