Tcl 8.4.
I have this namespace
tree:
namespace eval menu_tree {
#--------------------------------------------------------------------------
## Main Menu
namespace eval main_menu {
variable title "Main Menu"
}
#--------------------------------------------------------------------------
## Setup Menu
namespace eval setup_menu {
variable title "Show Setup Information"
}
#--------------------------------------------------------------------------
## Help Menu
namespace eval help_menu {
variable title "Show Help Information"
}
}
The idea was to have a function like this:
proc print_title {menu} {
puts $menu::title
}
This would work fine with global variables. However, from what I can find, using '$' with namespace names is required. I have tried to find the answer on the web, but nothing came up. Does anyone know how to do it, and if it is even possible?
Thank you, -Ilya.
Well, the key approach here is to keep in mind that "the original Tcl" did not have that "$" syntactic sugar at all. The original way to get the contents of a variable is a one-argument call to set
:
set foo bar ;# sets variable "foo" to contain the value "bar"
puts [set foo] ;# prints the value contained in variabe "foo"
Hence you'll probably should use something like
proc print_title {menu} {
puts [set ${menu}::title]
}
so that ${menu}::title
expands to the name of a variable then set
retrieves the value of that variable.
Note the usage of curly braces around the word "menu"--without them, Tcl would try to dereference a variable named "menu::title" which is probably not what you intended.
Another thing to observe is that the behaviour of print_title
highly depends on the contents of the "menu" argument: after it's expanded, the set
command must see a string which it should be able to resolve, and this is subject to a set of rules. It's hard to get further advice until more details is known though.
Refer to this question for more info about on that $
vs set
topic.
upvar
to alias it to a local variable name. upvar menu_tree::${menu}::title fruitbat; puts $fruitbat
Donal Fellows 2012-04-04 07:10
${menu}
was the trick. The code that finally worked is this:puts [set menu_tree::${menu}::title]
ilya1725 2012-04-04 01:17