Groups | Search | Server Info | Login | Register
Groups > comp.lang.tcl > #55610
| From | Emiliano <emiliano@example.invalid> |
|---|---|
| Newsgroups | comp.lang.tcl |
| Subject | Re: Bug in namespaces in 9.1? |
| Date | 2026-03-23 02:02 -0300 |
| Organization | A noiseless patient Spider |
| Message-ID | <20260323020244.a3f6f61e7b4ace9c1c4dc9c9@example.invalid> (permalink) |
| References | <10pot7p$3bbff$1@dont-email.me> <10ppf0v$3gm52$1@dont-email.me> <10ppins$3it6t$1@dont-email.me> |
On Sun, 22 Mar 2026 20:17:00 +0000
Simon Geard <simon@whiteowl.co.uk> wrote:
> >> Thanks for any help.
> >>
> >> Simon
> >>
> >
> > Dear Simon,
> > this is intended. You are using a miss-behaviour of 8.6, that it
> > searches a variable not starting with "::" in the global namespace, if
> > it is not found in the current namespace.
> >
> > How it is IMHO intended, e.g. use a namespace locale variable:
> >
> > namespace eval GUI {
> > variable x_counter 1
> > proc create {} {
> > variable x_counter
> > puts "\tGUI::create => $x_counter"
> > }
> > }
> >
> > What also works is full qualified namespaces:
> >
> > namespace eval GUI {
> > variable x_counter 1
> > proc create {} {
> > puts "\tGUI::create => $::GUI::x_counter"
> > }
> > }
> >
> > Why your own example worked:
> >
> > namespace eval GUI { ;# create namespace
> > variable x_counter 1 ;# create namespace local variable
> > proc create {} { ;# create namespace locale procedure
> > puts "\tGUI::create => $GUI::x_counter"
> > }
> > }
> >
> > The $GUI::x_counter specifies a variable in the namespace ::GUI::GUI
> > Namespace and variable does not exist.
> > In 8.6, this was looked-up in the global namespace and found the
> > variable in namespace "::GUI".
> >
> > Why this was an issue:
> >
> > set x_counter 1
> > namespace eval GUI {
> > set s_counter 1
> > }
> >
> > would pic the global variable, if it exists and create otherwise a
> > namespace local variable. In consequence, it was not possible to create
> > a namespace variable with the same name as a global variable.
> >
> > Hope this helps,
> > Harald
> >
> Thank you, that indeed was the problem. The example I gave was my
> attempt to distil the essence of a much larger tk app. The offending
> lines there were of the form
>
> ttk::entry $fr.e$i -textvariable GUI::x_letters($i)
> trace add variable GUI::x_letters($i) write GUI::reset_order
>
> I've now changed them all to
> ttk::entry $fr.e$i -textvariable ::GUI::x_letters($i)
> trace add variable GUI::x_letters($i) write ::GUI::reset_order
>
> And all is okay. [namespace current]::x_letters($i) also works.
Many years ago, when dealing over and over with this exact issue, I came
to the conclusion that I needed some helper functions for both variable
resolution (for -*variable options of widgets) and command resolution
(for callbacks) when working with Tk and namespaces.
My solution, which were wrappers for both [namespace which -command] and
[namespace which -variable], was
###########################################################################
# build fully qualifiied command prefixes
proc fqcmd {cmd args} {
set fqcmd [uplevel 1 [list namespace which -command $cmd]]
if {$fqcmd eq ""} {
return -code error "unknown command \"$cmd\""
}
return [linsert $args 0 $fqcmd]
}
###########################################################################
# build fully qualified varnames
proc fqvar {name} {
set fqvar [uplevel 1 [list namespace which -variable $name]]
if {$fqvar eq ""} {
return -code error "unknown variable \"$name\""
}
return $fqvar
}
With these helper functions, working with Tk and namespaces is a breeze.
Just call
% ttk::entry $fr.e$i -textvariable [fqvar x_letters]($i) ;#[1]
or
% trace add variable [fqvar x_letters]($i) write [fqcmd reset_order]
to resolve both variables and callback commands from the current namespace.
Even working with TclOO is immediate. If you want a callback to be a method
of the current object, just call [fqcmd my $method ?arg ...?], or if you want
a widget to use a variable from the current object use
[ttk::entry $parent.entry -textvariable [fqcmd $objvarname]].
The only shortcoming of this approach is that both variables and commands
must already exists when the [fqvar]/[fqcmd] command is called. For me,
this has proven to be a non issue. I just define the required variables or
procs before calling the GUI building code. This approach made the
transition from 8 to 9 virtually painless.
[1] The need to call [fqvar arrayname](element) instead of
[fqvar arrayname(element)] is due to bug#472113:
https://core.tcl-lang.org/tcl/tktview/472113
--
Emiliano
Back to comp.lang.tcl | Previous | Next — Previous in thread | Next in thread | Find similar
Bug in namespaces in 9.1? Simon Geard <simon@whiteowl.co.uk> - 2026-03-22 14:09 +0000
Re: Bug in namespaces in 9.1? Harald Oehlmann <wortkarg3@yahoo.com> - 2026-03-22 20:13 +0100
Re: Bug in namespaces in 9.1? Simon Geard <simon@whiteowl.co.uk> - 2026-03-22 20:17 +0000
Re: Bug in namespaces in 9.1? Emiliano <emiliano@example.invalid> - 2026-03-23 02:02 -0300
Re: Bug in namespaces in 9.1? Harald Oehlmann <wortkarg3@yahoo.com> - 2026-03-23 10:16 +0100
Re: Bug in namespaces in 9.1? Tristan Wibberley <tristan.wibberley+netnews2@alumni.manchester.ac.uk> - 2026-03-22 22:54 +0000
csiph-web