Why does [incr Tcl] patch the core?

[incr Tcl] includes a general-purpose
namespace facility
that forms the basis for the object system.
Namespaces can be used to package related procedures and their
global variables into well-defined libraries. They can also be used
to create "safe" command parsers. A namespace facility has been
requested by the Tcl development community for more than a year.
It made the top-five list of requested features at
Tcl/Tk Workshop '95 in Toronto.
John Ousterhout and his team at Sun Microsystems have
promised that this will be added to Tcl/Tk at some point, but
they have their hands full with other tasks.

[incr Tcl] must patch the core to include the namespace facility.
These patches are separated from the rest of [incr Tcl], with the
hope that someday soon they will be adopted by Sun and integrated
directly into the core. At that point, [incr Tcl] would revert to
being a "pure" extension. But until then, we are working hard to make
sure that [incr Tcl] works well with other extensions.

How do I use [incr Tcl] with other extensions?

[incr Tcl] comes with its own version of Tcl/Tk that has support for
namespaces. You must use this version of Tcl/Tk as a basis for other
applications. Hopefully, the namespace support will become a part
of the standard distribution some day soon.

You can add other extensions into the [incr Tcl] package by
following the usual instructions for Tcl/Tk:

Put the source code for the extension in the directory
itcl2.0, at the same level as the directories
tcl7.4 and tk4.0. You must compile
the extension with the include files and libraries for the
version of Tcl/Tk included in this release.

Copy tclAppInit.c or tkAppInit.c
from the standard distribution. Choose the appropriate version
according to your needs:

What is a scoped value?

A scoped value is a list with three elements: the "@scope"
keyword, a namespace context, and a value string. It provides a way of
capturing the namespace context for a command string or variable name,
so that when it is used later on, the proper context is restored.
For example, a scoped value representing a variable x
in the namespace ::foo would look like this:

@scope ::foo x

Scoped values can be passed around as ordinary strings at the Tcl
language level. They are usually created by wrapping code fragments
with the code command,
and variable names with the
scope command.
They are rarely generated by hand.

Any variable name starting with @scope is automatically
recognized as a global variable in the specified namespace.
Access is allowed from any namespace, even if the variable is
protected or private. Scoped variables can be used anywhere that
an ordinary variable name is recognized. For example, the following
statements are allowed:

Any command name starting with @scope is automatically
executed in the specified namespace. If additional arguments are
included, the command string is built by appending the extra arguments
as list elements to the end of the command string. This preserves the
integrity of the arguments, while keeping the code fragment
command as a flat string. For example:

@scope ::foo {.b configure} -text "Hello World!"

is equivalent to:

namespace ::foo {.b configure -text {Hello World!}}

Since scoped commands are executed in their namespace context,
they provide a way to access protected and private commands from
any other namespace. In effect, the @scope command is
a lot like the namespacecommand, but it allows extra
arguments to be appended to the command.

The scoped value mechanism takes some getting used to, but it is
obviously needed. With namespaces, commands and variable names are
no longer simple strings evaluated in the global scope; they have
a namespace context as well. The scoped value mechanism provides a
way of capturing and reporting the namespace context. It even allows
commands, variables and bindings to be copied from one widget
to another.

What namespace is used to evaluate commands or access variables
for a Tk widget?

Ordinary variable names and code fragments are evaluated in the
global namespace. This is consistent with vanilla Tcl/Tk, and
provides backward-compatibility with existing Tcl/Tk applications.

The checkbutton .cb is created within namespace
::foo. However, its -variable
and -command options are ordinary strings, and they
are evaluated in the global namespace. The name "x"
refers to the variable "::x", and the command
"show" refers to "::show".

If a widget is meant to use commands and variables in the local
namespace, it must be configured with
scoped values as follows:

This will cause an error when the button is pressed.
Ordinary code fragments like {say_hello "Joe Hacker"}
are evaluated in the global namespace, but the say_hello
procedure is defined within namespace ::foo. Therefore,
the command will fail, complaining that say_hello is
an "invalid command name".

The scoped value preserves the namespace context so that it can be
revived again later. When the button is pressed, the ::foo
context is automatically re-activated, and the say_hello command
is invoked in that context.

Note that the code command preserves its arguments as
individual list elements, just like the usual Tcl list
command. Many programmers already use the list command
to wrap up code fragments for other commands like after
and bind. The code command is a perfect
replacement for this. It formats the command and captures the
namespace context along the way.

Can a Tk widget access private variables in a namespace?

It can as long as variable names are wrapped up using the
scope command.

For example, suppose we have the following namespace with a
private variable:

namespace foo {
private variable state
}

Suppose we create a checkbutton in this namespace like this:

namespace foo {
checkbutton .cb -text "Toggle" -variable state
}

Ordinary variable names like state are evaluated in
the global namespace, so this checkbutton will work, but it is
really using the variable ::state to maintain its
state.

Suppose we try to qualify the variable with its namespace name:

namespace foo {
checkbutton .cb -text "Toggle" -variable foo::state
}

This will fail. Ordinary variable names are evaluated in
the global namespace, and since the foo::state
variable is private, it can only be accessed within the context
of namespace ::foo.

For this to work properly, the variable name must be wrapped up
in a scope command, which creates a
scoped value :

The scoped value preserves the namespace context so that it can be
revived again later. When the checkbutton needs to access its
variable, the ::foo context is automatically re-activated,
and the state variable is accessed in that context.

The scope command is quite similar to the code
command, except that it only takes one argument, and is better suited
to wrapping up variable names.

What is the difference between the window name and the
widget command?

With vanilla Tcl/Tk, the widget access command is the same as the
window name. If you create a button named ".b", then
you use the command ".b" to access it.

With namespaces, this is not necessarily true. If a widget is
created within a namespace, then its access command is protected
by the namespace. Within the namespace, the access command is indeed
the same as the window name. Outside of the namespace, however, you
should use the complete namespace path to access the widget:

The namespace qualifiers are only needed in conjunction with the
widget access command, which is always the first word
on a command line.

Many existing Tk applications assume that the window name can be
used as the access command. If the usual namespace rules described
above were strictly enforced, many existing applications would break.
For this reason, there is a "backward compatibility" mode in [incr Tcl]
that makes the distinction between the window name and the access
command much less of a problem. If an unknown command is recognized
as a Tk widget, the unknown procedure automatically uses
winfo command to find the access command for the widget.
With the "backward compatibility" mode, the following code still works:

Although this works, execution is a little slower. In general,
the following guidelines should be followed when using widgets
within namespaces:

When a widget is created within a namespace, it is a signal
that the widget is meant to be protected by the namespace.
The widget should not be accessed directly outside of the
namespace.

In bindings, the %q field
should be used instead of %W as the widget access
access command.

If a widget is meant to be generally available, it should be
created in the global namespace. This can be accomplished
from within a namespace like this:

namespace foo {
uplevel #0 button .b -text "Push Me"
}

or like this:

namespace foo {
button .b -text "Push Me"
rename .b ::.b
}

Library procedures can be written to operate on any window
using the winfo command
query.

What is the new "%q" field used for within bindings?

The %q field is replaced with the
qualified access command for the widget
receiving the event. The qualified access command is the
same as the window name in the %W field, but
with the leading namespace names needed to find the command.

A label named .x is created within the namespace
foo::bar. When the bindings are executed, the
%q field expands to the fully-qualified access
command for this widget, which is "::foo::bar::.x".

Note that when the widget is passed as a argument to other commands,
the %W field should be used instead of %q.
Commands like pack forget expect to see an ordinary
window name, and are confused by namespace qualifiers.

When do I need to use the "winfo command" query?

The winfo command query returns the
qualified access command for any window. This
is the same value that is substituted into the
%q field in widget bindings.

Suppose you need to write a procedure that will walk though the
widget hierarchy and change the background color of all windows.
Using vanilla Tcl/Tk, we could write this procedure as:

Note that variable names used in the argument list can change when
the body is redefined, but the argument list itself must have the
same meaning. If the class definition says that this method takes
one argument, then it must always take one argument. If some of
the arguments have default values, then they must have the same
default values when the method is redefined. Argument checking
can be suspended if the argument list is not specified, or if
it has the magic "args" argument:

It allows class definitions to be separated into "interface"
and "implementation" parts. The "interface" part shows at
a glance what command members are defined within a class,
and the "implementation" part supplies the bodies to support
class behavior.

If the "implementation" part is kept in a separate file,
it can be sourced again and again as bugs are being fixed
during interactive development.

When using the "tcl" mode in the emacs editor,
the "interface" and "implementation" parts can be kept in the
same file; as bugs are fixed, individual bodies can be
highlighted and sent to the test application.

How do I change the code associated with a public variable?

The "configuration" code associated with a public variable can be
supplied within the class definition, or redefined later using
the configbody command:

configbody is just like the body command,
but without an argument list specification.

How can I change a class definition?

Once a class has been defined, it cannot be redefined without first
deleting it. This rule is made for two reasons:

If you have changed the inheritance hierarchy or object
data members, this changes all objects in existance that belong
to that class. There is no way to update these objects on-the-fly;
any state information that they had would be corrupted.
Instead, they must be destroyed and recreated with the new class
definition.

In a large application, you may have two different definitions
for the same class, written by two different developers who
happened to use the same name. The current scheme catches
errors like this, instead of producing mysterious behavior.

It is easy to delete a class and start over. Just do:

delete class Foo

This will delete all objects that belong to class Foo,
and all classes derived from Foo.

As objects are being deleted, it is possible that a destructor could
produce an error, preventing the class from being deleted. Destructor
errors can be ignored if the class is destroyed in an absolute sense
using either:

delete namespace Foo
or
rename Foo ""

How do I delete an object if the destructor returns an error?

You can prevent an object from being destroyed by returning an error
in the destructor:

However, if you encounter errors during development, you may want
to destroy an object, ignoring any errors in the destructor. You
can do this by destroying the object in an absolute sense, by
deleting its access command:

rename x ""

Can I rename an object?

Yes. You can rename an object simply by renaming its access command.
The built-in "this" variable always reports the current object
access command, including namespace qualifiers:

What is the calling sequence for constructors/destructors?

The model for object construction/destruction follows C++ and other
object systems. The least-specific class in the hierarchy is
constructed first, followed by the next most-specific class,
and the next, and so on. All base class constructors are
guaranteed to be called before the derived class constructor
is invoked, even if the base class constructors are not mentioned
in the derived class.
For example:

Note that the construction order is exactly the opposite of the
what is reported by the info heritage command:

c0 info heritage
=> C B A1 A2

What happens if there is an error during construction?

An error during construction prevents an object from being created.

But suppose that a few of the base class constructors have been
invoked successfully, and an object is partially created. Suppose
that the constructors have opened files, created other objects, or
allocated some other resources. If an object is partially
constructed, it is fully destructed before it is discarded.
In the following example, the first two constructors are successful,
but the third returns an error:

Note that all destructors are automatically invoked, in an order
opposite the construction process, before returning the error
"cannot construct B". Any errors encountered in the destructors
are ignored.

How do I pass arguments to base class constructors?

There is now an optional "init" argument that you can supply with
each constructor. This argument should contain the constructor
invocations that you need to construct the base classes. It looks
like this:

The "init" argument is sandwiched between the argument list and the
body. If you don't supply one, [incr Tcl] automatically invokes
the base class constructors for you without any arguments
before entering the body of the constructor. That way, you can be sure
that all base classes are fully constructed before trying to construct
the derived class. It works a lot like the ":" initialization list
in C++; the syntax is even similar.

Do I have to specify the constructor/destructor body in the
class definition?

Yes. For other methods and procs, the body is optional; it can
be specified outside of the class definition using the body
command. But the special syntax of the constructor makes it impossible
to distinguish between the "init" code and the constructor body
unless both arguments are present.

If you would rather define the constructor/destructor outside of the
class, you must supply a null body within the class, and use the
body command to redefine it:

How can I add configuration options to ordinary objects?

Public variables act like configuration options for ordinary objects.
By default, each class has built-in methods configure
and cget that act like the Tk counterparts. They
provide automatic interface to all public variables, allowing the
client of an object to query its option settings and change them.
For example:

This class has three public attributes: the person's name, phone
number and e-mail address. Any extra args passed to
the constructor are treated as configuration options and passed
along to configure. A Person object
can be created like this:

Instead of five values like Tk, each configure configuration option
is represented by three values: the option name, the initial value
and the current value.

Sometimes it is useful to do error checking, or to perform some
other action whenever an option changes. Each public variable can
have its own bit of "configuration" code that gets invoked automatically
by the configure method when the option is set. For
example, suppose that we want to prevent the name from ever being
assigned the null string:

The configure method first assigns the new value to the
variable, and then invokes the configuration code. If this returns
an error, then the variable is set back to its old value, and the
configure method returns an error.

Suppose that whenever the e-mail address changes, we want to send
a test message to the new address. We could do that as follows:

Note that the configuration code for a public variable can be redefined
or specified outside of the class definition using the
configbody command.

How do I make an object data member an array?

Data members are just like ordinary variables. They can have simple
scalar values, or they can be used as arrays to hold many different
values. However, once a variable has been initialized as a scalar,
it cannot be treated as an array, and vice versa.

The trick to using arrays is not to specify an initial value when
the variable is declared, but to later initialize it in the constructor
or some other method. For example, the following class maintains a
collection of unique values, using an array for storage:

How do I make a common data member an array?

A common data member is just like an object variable, except that it
exists at the class scope, so there is only one real variable that
is shared by all objects in the class. Since it exists at the
class scope, it should be initialized at the class scope as well.
After all, if it is initialized within a constructor, it will be
reassigned each time an object is created.

To initialize a common data member as a scalar, you simply supply
a scalar value when the variable is declared:

class Foo {
private common colors "red green blue"
}

But to initialize it as an array, leave off the scalar initialization
value, and include a series of set statements right in
the body of the class definition:

Can I connect widget options like "-variable" for a checkbutton
or radiobutton to class data members?

Tk requires that all variables associated with widgets be "global".
With vanilla Tcl/Tk, this means that all widget-related variables
must be in the global scope. With namespaces, variables can be
"global" but contained within a namespace. For example:

Instead of creating a different global variable for each widget,
we have created one global array, and used a different slot for
each widget.

The same technique can be used in classes. Note that common data
members are really just global variables. Since they are declared
in the class definition, they need not be declared within each
method or proc by the usual "global" statement. The example above
can be adapted slightly to become an [incr Tk] mega-widget as follows:

If the global variable is not recognized in the local namespace,
it might be found in an imported namespace. For example, all
namespaces import the global namespace by default. Suppose you
want to access the env array at the global scope,
which contains environment variables. Since this variable
exists, it can be found automatically using its simple name:

The export procedure exports the current counter value
to the environment in a variable named "COUNTER".

Suppose you want to create a global variable in another scope, or
access a variable that is hidden by a variable in the local
namespace with the same name. For example, suppose there is a
variable called "num" in the global namespace.
You can access this variable by including the qualified namespace
path when the variable is declared. After the variable has been
declared, it can be accessed using its simple name:

In this example, the bonk procedure bumps the
num variable in the global namespace. If it doesn't
already exist when the procedure is called the first time, the
::num variable is automatically created.

Note the global command will fail if a variable cannot be accessed
in another namespace because it is protected or private.

Within a class, the global command works the same way.
It refers to variables that are "global" in the class namespace.
This includes variables that are declared as common
in the class definition, or other global variables that were
created later within methods and procs. If you want to access
global variables that belong to a different namespace, you have
to include the namespace path. For example:

If you construct an object in this class, you get the following output:

Bar x
=> Foo: in Bar
Bar: in Bar

It looks like the constructors are getting called in the proper
order--the base class Foo is constructed first,
followed by Bar. But notice that the report
method returns "in Bar", regardless of whether it is called
from within Foo or from within Bar.
All methods are implicitly virtual in [incr Tcl]. You will
always get the most-specific implementation for a method, even if
it is invoked from a base class. In C++, you have to declare a
method to be "virtual" to get this same behavior.

When you want to invoke a specific method, you can provide
an explicit namespace qualifier:

How can I redefine a built-in method like "configure", but still
call the built-in version?

Suppose you define a class that includes a method called
"configure":

class Foo {
method configure {x} {
puts "configuring: $x"
}
}

This method overrides the usual configure
method that is automatically added to handle public variables. This new
configure method behaves differently. It must
have one argument, and it merely prints a string displaying
that value.

Suppose instead of replacing the default configure method
you want to wrap it with some extra functionality. You can access
the default implementation using its body tag
"@itcl-builtin-configure":

In this example, we create a private method called
"_itcl_config". Its body is the same C procedure
that handles the usual configure operation, and
its argument list describes its command syntax. In effect,
we renamed the usual configure method to
"_itcl_config".
We then create another method called configure
that massages the argument list, and eventually calls
_itcl_config to do its dirty work.

How do I access the options of a component created in a base
class, if those options were not kept or renamed when the
component was created?

The [incr Tk] base classes itk::Widget and
itk::Toplevel define the "hull" component that
embodies a mega-widget. By default, only the -background
and -cursor options are integrated into the composite
option list. But suppose that for your widget, you also want to
add controls for the borderwidth and relief. You can add options
for components created in a base class as follows:

You can remove options in a similar manner, using
"itk_option remove ...". However, the "remove"
function should be used sparingly. In the object-oriented philosophy,
a derived class should behave exactly like a base class, with perhaps
some extra functionality. It should not have missing features.

The "itk_option add ..." command allows options to be
specified one of two ways:

component.option
for an option belonging to a specific component.

class::option
for an option defined within a mega-widget class.

In both cases, option is a name like
"-borderwidth" without the leading "-" sign.

How do I override an option defined or added in a base class?

Any option that was defined or added in a base class can be
suppressed in a derived class using "itk_option remove ...".
The option can then be redefined in the derived class to perform
a different function.

Without the "itk_option remove" command, the code
fragments for both of the -foo options would be
executed each time the composite -foo option is
configured. In the example above, the Base::foo
option is suppressed in all Derived class widgets, so only
the Derived::foo option remains.

I defined some options using "itk_option", but they don't
show up when the widget is created. What went wrong?

Chances are, you forgot to invoke itk_initialize
within one or more of the mega-widget constructors.

Each mega-widget class should contain a constructor that follows
this template:

The itk_initialize method integrates options defined
via "itk_option define ..." in the current class, and
it applies any configuration options passed in through the constructor.
If it is not called for some reason, options may not be initialized
properly, or may not get integrated at all. Note that the values
in the itk_option array, and methods like
configure and cget, should not be
used until after the option list has been initialized.