Reputation:
I saw some code in TCL like this:
namespace eval ::info {
set count 0;
set id 1;
set role admin;
namespace export *
}
proc ::info::setcount {
set ::info::count 0;
}
proc ::info::setId {
set ::info::id 1;
}
proc ::info::setRole {
set ::info::role user;
}
There are three variables defined in namespace ::info, but that three procs(setcount setId setRole) are not declared in the namespace, seems like they are defined outside of ::info, is this allowed? how does this work?
Upvotes: 3
Views: 6114
Reputation: 16262
The namespace eval
command
Procs defined from within a namespace (which is all procs, since the default namespace is ::)
As such
namespace eval bob {
namespace eval joe {
proc proc1 {} {}
}
proc proc2 {} {}
proc ::proc3 {} {}
proc joe::proc4 {} {}
}
proc proc5 {} {}
proc bob::joe::proc6 {} {}
proc ::bob::joe::proc7 {} {}
The following commands will exist
::bob::joe::proc1
::bob::proc2
::proc3
::bob::joe::proc4
::proc5
::bob::joe::proc6
::bob::joe::proc7
Notice that commands in the global namespace, when called from the global namespace, can be preceeded by a ::
or not. The same is true of commands in any namespace.
namespace eval bob {
proc2 ;# calls ::bob::proc2
::proc5 ;# calls ::proc5 (proc5 in the global namespace)
joe::proc4 ;# calls ::bob::joe::proc4
}
It is worth noting that a raw command name (with no namespace qualifiers at all) will look in the current namespace and then, if it doesn't find the command there, the global namespace.
namespace eval bob {
proc5 ;# calls ::proc5 since there is no ::bob::proc5
}
Upvotes: 4
Reputation: 137567
The procedures are defined in the ::info
namespace. They're just not inside the scope of the namespace eval
, a command that just creates the namespace if necessary and then executes the given script within that context. Being executed within the context of a namespace changes how proc
places commands that it creates when the names of those commands are not fully-qualified. The namespace exists independently of the namespace eval
call.
The variables have to be declared in the namespace though; that avoids some really nasty trouble with resolution of variables that can catch people out.
Personally, I prefer to write code like this:
namespace eval ::foo {
proc bar ... {
...
}
}
But I know that other people disagree with me. Write what you prefer, as Tcl works just fine with either scheme.
Upvotes: 5