Groups | Search | Server Info | Login | Register


Groups > comp.lang.tcl > #55610

Re: Bug in namespaces in 9.1?

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>

Show all headers | View raw


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 | NextPrevious in thread | Next in thread | Find similar


Thread

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