Frequently Asked Questions



Following is a list of frequently asked questions related to the [incr Tcl] package for Tcl/Tk . The questions and answers reply to release 2.0 and beyond.

General

Namespaces

[incr Tcl] Object System

[incr Tk] Mega-Widgets


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:

  1. 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.

  2. Copy tclAppInit.c or tkAppInit.c from the standard distribution. Choose the appropriate version according to your needs:
      tcl7.4/tclAppInit.c .... Tcl with namespaces
      tk4.0/tkAppInit.c ...... Tcl/Tk with namespaces
      itcl/tclAppInit.c ...... Tcl with namespaces and [incr Tcl]
      itk/tkAppInit.c ........ Tcl/Tk with namespaces and [incr Tcl]/[incr Tk]
    

  3. Each extension should have an initialization function with a name like XXX_Init(). The BLT package, for example, has a function Blt_Init().

    • Include the declarations for any initialization routines at the top of the tclAppInit.c or tkAppInit.c file.

    • Within the body of Tcl_AppInit(), add a call to the initialization routines. It should look something like this:
          if (Itcl_Init(interp) == TCL_ERROR) {
              return TCL_ERROR;
          }
          if (Itk_Init(interp) == TCL_ERROR) {
              return TCL_ERROR;
          }
          if (Blt_Init(interp) == TCL_ERROR) {
              return TCL_ERROR;
          }
      
      In this example we have integrated BLT in with [incr Tcl] and [incr Tk].

  4. Link your application with the appropriate libraries:
      libtcl.a ............ Tcl with namespaces
      libtk.a ............. Tk with namespaces
      libitcl.a ........... [incr Tcl]
      libitk.a ............ [incr Tk]
      -lX11 ............... X11 library
    

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:

    namespace foo {
        variable mode "1"
    }
    set {@scope ::foo mode} 3
    puts "value = ${@scope ::foo mode}"
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.

Consider the following example:

    proc show {mesg} {
        puts "global: $mesg"
    }
    namespace foo {
        variable x
        proc show {mesg} {
            puts "foo: $mesg"
        }

        checkbutton .cb -variable x -command {show "state = $x"}
    }
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:

    namespace foo {
        .cb configure \
            -variable [scope x] \
            -command [code {show "state = $x"}]
    }

Can a Tk widget access private commands in a namespace?

It can as long as code fragments are wrapped up using the code command.

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

    namespace foo {
        private proc say_hello {name} {
            puts "hello $name!"
        }
    }
Suppose we create a button in this namespace and configure it to call say_hello:
    namespace foo {
        button .b -text "Push Me" \
            -command {say_hello "Joe Hacker"}
    }
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".

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

    namespace foo {
        button .b -text "Push Me" \
            -command {foo::say_hello "Joe Hacker"}
    }
Again, this will fail. Ordinary code fragments are evaluated in the global namespace, and since the foo::say_hello command is private, it can only be accessed within the context of namespace ::foo.

For this to work properly, the code fragment must be wrapped up in a code command, which creates a scoped value :

    namespace foo {
        button .b -text "Push Me" \
            -command [code say_hello "Joe Hacker"]
    }
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 :

    namespace foo {
        checkbutton .cb -text "Toggle" -variable [scope state]
    }
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:

    namespace foo {
        label .x -text "X"
        .x configure -background red
    }
    foo::.x configure -relief raised
You can still use the window name ".x" as an argument to other Tk commands, regardless of the namespace context:
    namespace foo {
        set w [winfo width .x]
    }
    set w [winfo width .x]

    pack .x
    destroy .x
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:

    namespace foo {
        label .x -text "X"
        .x configure -background red
    }
    .x configure -relief raised
Although this works, execution is a little slower. In general, the following guidelines should be followed when using widgets within namespaces:

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.

Consider the following example:

    namespace foo {
        namespace bar {
            label .x -text "Hello World!" -background white
            pack .x

            bind .x <Enter> {%q configure -background red}
            bind .x <Leave> {%q configure -background white}
            bind .x <ButtonPress-1> {pack forget %W}
        }
    }
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:

    proc whiteout {win} {
        $win configure -background white
        foreach kid [winfo children $win] {
            whiteout $kid
        }
    }
This will also work in [incr Tcl], due to the "backward compatibility" mode. However, a better way of writing this procedure is as follows:
    proc whiteout {win} {
        [winfo command $win] configure -background white
        foreach kid [winfo children $win] {
            whiteout $kid
        }
    }

How do I make changes to method bodies during development?

Once a class has been defined, body of a method or proc can be redefined using the body command:
    class Foo {
        method test {x} {
            return "original implementation"
        }
    }

    body Foo::test {y} {
        return "redefined"
    }
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:
    class Foo {
        method test {args}
    }

    body Foo::test {x} {
        return "redefined"
    }
    body Foo::test {x y z} {
        return "redefined again"
    }
The body command improves things two ways:
  1. 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.

  2. 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:
    class Foo {
        public variable x 0 {
            puts "original implementation"
        }
    }

    configbody Foo::x {
        puts "redefined"
    }
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:
  1. 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.
  2. 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:
    class Counter {
        private variable val 0
        destructor {
            if {$val != 0} {
                error "must reset first"
            }
        }
        method bump {} {
            incr val
        }
        method reset {} {
            set val 0
        }
    }

    Counter x
    x bump
    x bump

    delete object x
     => must reset first 
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:
    class Foo {
        method whoami {} {
            return $this
        }
    }

    Foo x
    x whoami
     => ::x 

    rename x bar::different
    namespace bar {different whoami}
     => ::bar::different

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:
    class A1 {
        constructor {} {puts "constructing A1"}
    }
    class A2 {
        constructor {} {puts "constructing A2"}
    }
    class B {
        inherit A1 A2
        constructor {} {puts "constructing B"}
    }
    class C {
        inherit B
        constructor {} {puts "constructing C"}
    }

    C c0
     => constructing A2
        constructing A1
        constructing B
        constructing C 
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:

    class A1 {
        constructor {} {puts "constructing A1"}
        destructor {puts "destructing A1"}
    }
    class A2 {
        constructor {} {puts "constructing A2"}
        destructor {puts "destructing A2"}
    }
    class B {
        inherit A1 A2
        constructor {} {error "cannot construct B"}
        destructor {puts "destructing B"}
    }
    class C {
        inherit B
        constructor {} {puts "constructing C"}
        destructor {puts "destructing C"}
    }

    C c0
     => constructing A2
        constructing A1
        destructing C
        destructing B
        destructing A1
        destructing A2
        cannot construct B 
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:
    class Base {
        constructor {x y} {
            puts "Base: $x $y"
        }
    }
    class Derived {
        constructor {x y z} {
            Base::constructor $x $y
        } {
            puts "Derived: $x $y $z"
        }
    }
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:

    class Foo {
        constructor {args} {}
        destructor {}
    }

    body Foo::constructor {args} {
        return "this is the real constructor"
    }
    body Foo::destructor {} {
        return "this is the real destructor"
    }

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:
    class Person {
        public variable name ""
        public variable phone ""
        public variable email ""

        constructor {args} {
            eval configure $args
        }
    }
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:
    Person bob -name "Cyber Bob" \
        -phone "555-4bob" \
        -email "cbob@foo.com"
and reconfigured like this:
    bob configure
     => {-email {} cbob@foo.com} {-name {} {Cyber Bob}} {-phone {} 555-4bob} 

    bob configure -phone
     => -phone {} 555-4bob

    bob configure -phone 1-800-num-4bob
     => 

    bob cget -phone
     => 1-800-num-4bob
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:

    class Person {
        public variable name "" {
            if {$name == ""} {
                error "no name specified"
            }
        }
        ...
    }
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:

    class Person {
        public variable email "" {
            set fid [open "| /usr/ucb/mail $email" w]
            puts $fid "~s Test message"
            puts $fid "Hello $name!"
            puts $fid "This is a test for your new e-mail address"
            close $fid
        }
        ...
    }
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:

    class Collection {
        private variable items
        constructor {args} {
            eval add $args
        }
        method add {args} {
            foreach val $args {
                set items($val) $val
            }
        }
        method get {} {
            return [array names items]
        }
    }

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:
    class Foo {
        private common colors
        set colors(red) #ff0000
        set colors(green) #00ff00
        set colors(blue) #0000ff
    }
You can also use the array command to initialize arrays:
    class Foo {
        private common colors
        array set colors {
            red #ff0000
            green #00ff00
            blue #0000ff
        }
    }

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:
    namespace Toggle {
        private variable state

        proc create {name args} {
            global state
            checkbutton $name -text "Push Me" \
                -variable [scope state($name)]

            eval $name configure $args
        }
    }

    Toggle::create .c -selectcolor green
    pack .c
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:

    class Toggle {
        inherit itk::Widget

        private common state

        constructor {args} {
            itk_component add toggle {
                checkbutton $itk_component(hull).tog \
                    -variable [scope state($this)]
            }
            pack $itk_component(hull).tog

            eval itk_initialize $args
        }

        method get {} {
            return $state($this)
        }
    }

    Toggle .c -text "Push Me" -selectcolor green
    pack .c
There is one state array hidden in class Toggle that keeps track of all Toggle widgets. Each slot is parameterized by the object name $this.

How do I access variables at the global scope?

When you use the global command within a namespace, it refers to variables that are "global" in that scope. For example:
    namespace counter {
        private variable num 0

        proc bump {{by 1}} {
            global num
            incr num $by
        }
    }
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:
    namespace counter {
        proc export {} {
            global num env
            set env(COUNTER) $num
        }
    }
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:

    namespace counter {
        private variable num 0
        proc bump {{by 1}} {
            global num
            incr num $by
        }
        proc bonk {{by 1}} {
            global ::num
            incr num $by
        }
    }
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:

    class counter {
        private common num 0

        proc bump {{by 1}} {
            global num       ;# won't hurt, but not needed
            incr num $by
        }
        proc bonk {{by 1}} {
            global ::num     ;# access "num" in global namespace
            incr num $by
        }
    }
Since the counter::num variable is already known to be "common", the global statement is not needed. To access the ::num variable, however, it must be declared global.

Why doesn't my base class method get called?

Suppose you have some classes defined like this:
    class Foo {
        constructor {} { puts "Foo: [report]" }
        method report {} { return "in Foo" }
    }
    class Bar {
        inherit Foo

        constructor {} { puts "Bar: [report]" }
        method report {} { return "in Bar" }
    }
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:

    class Foo {
        constructor {} { puts "Foo: [Foo::report]" }
        method report {} { return "in Foo" }
    }
    class Bar {
        inherit Foo

        constructor {} { puts "Bar: [Bar::report]" }
        method report {} { return "in Bar" }
    }

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

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":

    class Foo {
        method configure {args} {
            puts "configuring: $args"
            eval _itcl_config $args
        }

        private method _itcl_config {option args} \
            @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.

You can perform a similar trick with any of the built-in methods:

    cget .............. @itcl-builtin-cget
    configure ......... @itcl-builtin-configure
    isa ............... @itcl-builtin-isa

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:
    class Toggle {
        inherit itk::Widget

        constructor {args} {
            itk_option add hull.borderwidth hull.relief

            itk_component add toggle { ... } { ... }
            ...
            eval itk_initialize $args
        }
    }
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:

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.

For example, the following base class has an option "-foo":

    class Base {
        inherit Widget
        constructor {args} {
            eval itk_initialize $args
        }

        itk_option define -foo foo Foo "" {
            puts "Base: $itk_option(-foo)"
        }
    }
We can override this option in a derived class by removing the part contributed by the base class, and redefining the option in the derived class:
    class Derived {
        inherit Base

        constructor {args} {
            itk_option remove Base::foo
            eval itk_initialize $args
        }
        itk_option define -foo foo Foo "" {
            puts "Derived: $itk_option(-foo)"
        }
    }
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:

    constructor {args} {
        itk_option add ...                  << add any desired options
                                               missing from base classes 

        itk_component add name {...} {...}  << add components
        itk_component add name {...} {...}
        itk_component add name {...} {...}

        eval itk_initialize $args           << update option list

        ...                                 << call configure
                                               or do anything else that
                                               that depends on options 
    }
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.

Back