Groups | Search | Server Info | Login | Register


Groups > comp.lang.tcl > #55613

Re: Bug in namespaces in 9.1?

From Harald Oehlmann <wortkarg3@yahoo.com>
Newsgroups comp.lang.tcl
Subject Re: Bug in namespaces in 9.1?
Date 2026-03-23 10:16 +0100
Organization A noiseless patient Spider
Message-ID <10pr0e2$35k$1@dont-email.me> (permalink)
References <10pot7p$3bbff$1@dont-email.me> <10ppf0v$3gm52$1@dont-email.me> <10ppins$3it6t$1@dont-email.me> <20260323020244.a3f6f61e7b4ace9c1c4dc9c9@example.invalid>

Show all headers | View raw


Am 23.03.2026 um 06:02 schrieb Emiliano:
> 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
> 

Remark, that another missbehaviour in TCL 8.6 was fixed in 9.0:
"namespace which -variable" now also works for arrays.

So, in 9.0 one can do:

ttk::entry $fr.e$i -textvariable [namespace which -variable x_letters($i)]

Harald

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