tcltest: do a better job of cleanup up after tests
[jimtcl.git] / README.namespaces
blobef50769f96c9b72ce5a5f48ff2f25071a64b0ae6
1 Lightweight Namespaces for Jim Tcl
2 ==================================
4 There are two broad requirements for namespace support in Jim Tcl.
6 1. To allow code from multiple sources while reducing the chance of name clashes
7 2. To simplify porting existing Tcl code which uses namespaces
9 This proposal addresses both of these requirements, with the following
10 additional requirements imposed by Jim Tcl.
12 3. Support for namespaces should be optional, with the space and time overhead
13    when namespaces are disabled as close to zero as possible.
14 4. The implementation should be small and reasonably efficient.
16 To further expand on requirement (2), the goal is not to be able to run
17 any Tcl scripts using namespaces with no changes. Rather, scripts
18 which use namespaces in a straightforward manner, should be easily
19 ported with changes which are compatible with Tcl.
21 Implicit namespaces
22 -------------------
23 Rather than supporting explicit namespaces as Tcl does, Jim Tcl
24 supports implicit namespaces. Any procedure or variable which
25 is defined with a name containing ::, is implicitly scoped within
26 a namespace.
28 For example, the following procedure and variable are created
29 in the namespace 'test'
31 proc ::test::myproc {} {
32   puts "I am in namespace [namespace current]"
34 set ::test::myvar 3
36 This approach allows much of the existing variable and command
37 resolution machinery to be used with little change. It also means
38 that it is possible to simply define a namespace-scoped variable
39 or procedure without first creating the namespace, and similarly,
40 namespaces "disappear" when all variables and procedures defined
41 with the namespace scope are deleted.
43 Namespaces, procedures and call frames
44 --------------------------------------
45 When namespace support is enabled (at build time), each procedure has an associated
46 namespace (based on the procedure name). When the procedure is evaluated,
47 the namespace for the created call frame is set to the namespace associated
48 with the procedure.
50 Command resolution is based on the namespace of the current call frame.
51 An unscoped command name will first be looked up in the current namespace,
52 and then in the global namespace.
54 This also means that commands which do not create a call frame (such as commands
55 implemented in C) do not have an associated namespace.
57 Similarly to Tcl, namespace eval introduces a temporary, anonymous
58 call frame with the associated namespace. For example, the following
59 will return "::test,1".
61 namespace eval test {
62         puts [namespace current],[info level]
65 Variable resolution
66 -------------------
67 The variable command in Jim Tcl has the same syntax as Tcl, but is closer in behaviour to the global command.
68 The variable command creates a link from a local variable to a namespace variable, possibly initialising it.
70 For example, the following procedure uses 'variable' to initialise and access myvar.
72 proc ::test::myproc {} {
73   variable myvar 4
74   incr myvar
77 Note that there is no automatic resolution of namespace variables.
78 For example, the following will *not* work.
80 namespace eval ::test {
81   variable myvar 4
83 namespace eval ::test {
84   # This will increment a local variable, not ::test::myvar
85   incr myvar
88 And similarly, the following will only access local variables
90 set x 3
91 namespace eval ::test {
92         # This will increment a local variable, not ::x
93         incr x
94         # This will also increment a local variable
95         incr abc::def
98 In the same way that variable resolution does not "fall back" to
99 global variables, it also does not "fall back" to namespace variables.
101 This approach allows name resolution to be simpler and more efficient
102 since it uses the same variable linking mechanism as upvar/global
103 and it allows namespaces to be implicit. It also solves the "creative
104 writing" problem where a variable may be created in an unintentional
105 scope.
107 The namespace command
108 ---------------------
109 Currently, the following namespace commands are supported.
111 * current - returns the current, fully-qualified namespace
112 * eval - evaluates a script in a namespace (introduces a call frame)
113 * qualifiers, tail, parent - note that these do not check for existence
114 * code, inscope - implemented
115 * delete - deletes all variables and commands with the namespace prefix
116 * which - implemented
117 * upvar - implemented
119 namespace children, exists, path
120 --------------------------------
121 With implicit namespaces, the namespace exists and namespace children commands
122 are expensive to implement and are of limited use. Checking the existence
123 of a namespace can be better done by checking for the existence of a known procedure
124 or variable in the namespace.
126 Command resolution is always done by first looking in the namespace and then
127 at the global scope, so namespace path is not required.
129 namespace ensemble
130 ------------------
131 The namespace ensemble command is not currently supported. A future version
132 of Jim Tcl will have a general-purpose ensemble creation and manipulation
133 mechanism and namespace ensemble will be implemented in terms of that mechanism.
135 namespace import, export, forget, origin
136 ----------------------------------------
137 Since Jim Tcl namespaces are implicit, there is no location to store export patterns.
138 Therefore the namespace export command is a dummy command which does nothing.
139 All procedures in a namespace are considered to be exported.
141 The namespace import command works by creating aliases to the target namespace
142 procedures.
144 namespace forget is not implemented.
146 namespace origin understands aliases created by namespace import
147 and can return the original command.
149 namespace unknown
150 -----------------
151 If an undefined command is invoked, the "unknown" command is invoked.
152 The same namespace resolution rules apply for the unknown command.
153 This means that in the following example, test::unknown will be invoked
154 for the missing command rather than the global ::unknown.
156 proc unknown {args} {
157         puts "global unknown"
160 proc test::unknown {args} {
161         puts "test unknown"
164 namespace eval test {
165         bogus
168 This approach requires no special support and provides enough flexibility that
169 the namespace unknown command is not implemented.
171 Porting namespace code from Tcl to Jim Tcl
172 ------------------------------------------
173 For most code, the following changes will be sufficient to port code.
175 1. Canonicalise namespace names. For example, ::ns:: should be written
176    as ::ns or ns as appropriate, and excess colons should be removed.
177    For example ::ns:::blah should be written as ::ns::blah
178    (Note that the only "excess colon" case supported is ::::abc
179    in order to support [namespace current]::abc in the global namespace)
181 2. The variable command should be used within namespace eval to link
182    to namespace variables, and access to variables in other namespaces
183    should be fully qualified
185 Changes in the core Jim Tcl
186 ---------------------------
187 Previously Jim Tcl performed no scoping of command names.  i.e. The
188 ::format command was considered different from the format command.
190 Even if namespace support is disabled, the command resolution will
191 recognised global scoping of commands and treat these as identical.