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
- Mixing with Other Extensions
Namespaces
- Scope
- What is a scoped value?
- What namespace is used to evaluate commands or access variables for a Tk widget?
- Can a Tk widget access private commands in a namespace?
- Can a Tk widget access private variables in a namespace?
- Accessing Widgets
[incr Tcl] Object System
- Interactive development
- How do I make changes to method bodies during development?
- How do I change the code associated with a public variable?
- How can I change a class definition?
- How do I delete an object if the destructor returns an error?
- Can I rename an object?
- Construction and Destruction
- What is the calling sequence for constructors/destructors?
- What happens if there is an error during construction?
- How do I pass arguments to base class constructors?
- Do I have to specify the constructor/destructor body in the class definition?
- Variables
- How can I add configuration options to ordinary objects?
- How do I make an object data member an array?
- How do I make a common data member an array?
- Can I connect widget options like "-variable" for a checkbutton or radiobutton to class data members?
- How do I access variables at the global scope?
- Methods
[incr Tk] Mega-Widgets
- Options
- 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?
- How do I override an option defined or added in a base class?
- I defined some options using "itk_option", but they don't show up when the widget is created. What went wrong?
[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.
You can add other extensions into the [incr Tcl] package by following the usual instructions for Tcl/Tk:
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.
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]
_Init(). The BLT package, for example,
has a function Blt_Init().
tclAppInit.c or
tkAppInit.c file.
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].
libtcl.a ............ Tcl with namespaces libtk.a ............. Tk with namespaces libitcl.a ........... [incr Tcl] libitk.a ............ [incr Tk] -lX11 ............... X11 library
@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.
Consider the following example:
If a widget is meant to use commands and variables in the local
namespace, it must be configured with
scoped values as follows:
For example, suppose we have the following namespace with a
private procedure:
Suppose we try to qualify the command with its namespace name:
For this to work properly, the code fragment must be wrapped up
in a
Note that the
For example, suppose we have the following namespace with a
private variable:
Suppose we try to qualify the variable with its namespace name:
For this to work properly, the variable name must be wrapped up
in a
The
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.
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".
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.
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".
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. 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. 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.
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.
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. 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. 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.
.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:
%W as the widget access
access command.
namespace foo {
uplevel #0 button .b -text "Push Me"
}
or like this:
namespace foo {
button .b -text "Push Me"
rename .b ::.b
}
%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.
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
}
}
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:
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.
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.
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 ""
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 ""
class Foo {
method whoami {} {
return $this
}
}
Foo x
x whoami
=> ::x
rename x bar::different
namespace bar {different whoami}
=> ::bar::different
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
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.
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.
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"
}
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.
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]
}
}
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
}
}
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.
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.
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
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
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:
component.option class::option option is a name like
"-borderwidth" without the leading "-" sign.
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.
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.