Previous Page Next Page

Chapter 3

This chapter focuses on the concepts of classes, objects and messages, the basis of the [incr Tcl] language. 


Problem solving using [incr Tcl] involves classifying objects according to their similarities and differences. A class defines the behavior of similar objects by specifying their insides--the variables they contain and the methods available for responding to messages sent to them.

Every object is an instance (member) of a class. 

An object's internal variables are called instance variables; they are themselves containers for other objects.


A Point refers to a position within a two-dimensional array. It has two instance variables: x, the horizontal coordinate, and y, the vertical coordinate. In order for a graphics tool to address the pixels on a display or output device, there must be a coordinate system imposed on the device. The coordinate system used by Smalltalk/V is shown in Figure 3.1.

Figure 3.1
Coordinate System

To evaluate the following source-code, start the program tkcon and enter (or copy and paste) the lines to the prompt (%).

package require Itcl

itcl::class Point {
variable x
variable y

constructor {{aNumberX 0} {aNumberY 0}} {
set x $aNumberX
set y $aNumberY
return $this}
method x: {aNumber}
method y: {aNumber}
method x {}
method y {}
method is {aNumberX aNumberY}
method printOn: {aStream}
method printString
method = {aPoint}
method += {aPoint}
method + {aPoint}

The command "package require Itcl" loads the [incr Tcl] extension. The "itcl::class" command starts a class definition. The class Point has the variables x and y. The methods will be explained shortly. With the source code above it is possible to create Point objects.
Copy and paste the following lines to the prompt:

Point a 5 10
Point b

The first line creates a Point object a with the coordinates 5 and 10. The second line creates object b with default coordinates 0 and 0. See the constructor definition above.

All access to the variables in a class is done through access methods. To set the variables to a value execute the following:

itcl::body Point::x: {aNumber} {
set x $aNumber}

itcl::body Point::y: {aNumber} {
set y $aNumber}

a x: 1
a y: 2

The variables x and y of object a have now the values 1 and 2. To get the variables some more access methods are needed

itcl::body Point::x {} {
return $x}

itcl::body Point::y {} {
return $y}

a x
a y

The use of x: y: methods to set a Point object are inconvenient. Some better set method is:

itcl::body Point::is {aNumberX aNumberY} {
set x $aNumberX
set y $aNumberY}

a is 1 2

To get a string representation of the object there is the printString method:

itcl::body Point::printString {} {
return "$x @ $y"}

puts "[a printString]"

For output to a stream there is the printOn: method. The console window is the stream stdout.

itcl::body Point::printOn: {aStream} {
puts -nonewline $aStream "$x @ $y"}

a printOn: stdout

The method = copies a Point object.

itcl::body Point::= {aPoint} {
set x [$aPoint x]
set y [$aPoint y]}

b = a
puts "[a print] ; [b print]"

The above methods are typical for most classes. The following methods implement the algorithms.  The increment a Point object is the first:

itcl::body Point::+= {aPoint} {
set x [expr $x + [$aPoint x]]
set y [expr $y + [$aPoint y]]}

a += b
puts "[a print]"

The sum method has to create a new Point object. This is done with #auto, a build-in method in every [incr Tcl] class.

itcl::body Point::+ {aPoint} {
set sum [Point #auto]
$sum x: [expr $x + [$aPoint x]]
$sum y: [expr $y + [$aPoint y]]
return $sum}

Point c
c = [a + b]
puts "[c print] = [a print] + [b print]"

Many more methods can be added to the Point class. But the class concept should be clear now: bring data and algorithms together in one housing. This housing introduces a new abstraction level to programming.


A Set stores arbitrary objects. A Set does not store the same object more than once. The Set class definition is:

package require Itcl

itcl::class Set {
variable contents ""

method add: {anObject}
method do: {varName aBlock}
method includes: {anObject}
method remove:ifAbsent: {anObject aBlock}
method size {}

Set s

The method add: adds one object to the set.

itcl::body Set::add: {anObject} {
# "Answer anObject. Add anObject to the receiver
# if the receiver does not already contain it."
if {[lsearch $contents $anObject] < 0} {
lappend contents $anObject
return $anObject}

s add: 1
s add: "anton"
s add: {"Mona" "Lisa"}
s add: 3.0
s add: "anton"
s add: 3.0

The do: method is a new control structure like the foreach command.

itcl::body Set::do: {varName aBlock} {
# "Answer the receiver. For each element in the receiver,
# evaluate aBlock with that element as the argument."
upvar $varName v
foreach v $contents {
uplevel $aBlock}}

s do: element {puts "$element"}

The includes: method is a test.

itcl::body Set::includes: {anObject} {
# "Answer true if the receiver includes anObject
# as one of its elements, else answer false."
if {[lsearch $contents $anObject] >= 0} {
return 1
} else {
return 0}}

puts [s includes: 3]
puts [s includes: 3.0]
puts [s includes: {"Mona" "Lisa"}]

The remove:ifAbsent: removes an object. The block is evaluated if there is no object to remove.

itcl::body Set::remove:ifAbsent: {anObject aBlock} {
#"Answer anObject. Remove the element anObject from
# the receiver collection. If anObject is not an
# element of the receiver, aBlock is evaluated
# (with no arguments)."
set index [lsearch $contents $anObject]
if {$index < 0} {
return [uplevel $aBlock]
set contents [concat \
[lrange $contents 0 [expr $index-1]] \
[lrange $contents [expr $index+1] end]]
return $anObject}

s remove:ifAbsent: "anton" {puts "nothing to delete"}
s remove:ifAbsent: "anton" {puts "nothing to delete"}

The size method returns the number of elements in the set.

itcl::body Set::size {} {
# "Answer the number of elements contained
# in the receiver."
return [llength $contents]}

puts [s size]

This example for a Set class is not complete. But now there are enough objects and messages to talk about in the system.

What You've Now Learned

At this point, you should be familiar with:

If you want to review any of these topics, simply refer back to the appropriate section in this chapter. 

Previous Page Next Page