Problems and Solutions

On this page I will write about little problems which I have with Tcl and about how I solve those problems. I think that these problems are so small, they don't deserve a whole wiki page, but are worth mentioning anyway.

Anybody is welcome to add their problems and solutions, since this is after all a wiki.

JMPB


When looking at most modules you see, code like this is everywhere:

proc ::base64::encode { ... } { ...
...
proc ::base64::decode { ... } { ...
...

Lots of typing to simply put a few procs into a separate namespace. It may seem that this is a trivial issue - and it is. But I think it is worth looking for an alternative. So, I simply thought this one up:

proc _proc { name args body } {
    proc "::${::_namespace}::$name" args body
}

To use:

set _namespace "base64"
...
_proc encode { ... } { ...
...
_proc decode { ... } { ...
...

I have not simply temporarily replaced proc because that could mess up when other modules are loaded.

Would be happy to hear about improvements to this. JMPB


MG You can also do

namespace eval ::mynamespace {
    proc a {} {return "this is ::mynamespace::a"}
    proc b {} {return "this is ::mynamespace::b"}
}

I think the reason that most people write it out in full for each proc is so that it's easy, at a glance, to see exactly what/where each proc is. (If you have 20 or 30 reasonably large procs, you could have to do a lot of scrolling to find the namespace eval they're inside to figure out what the proc is actually called.)


2006-12-29 jmpb - So how about access to namespace variables? Is there some way of accessing the variables inside a namespace eval without needing to know the namespace name (i.e. ::..::varName)? Or would upvar be preferred? Upvar takes quite some speed from the script from what I heard, so...

MG There are a couple of ways I'm aware of.

namespace eval ::mynamespace {
    variable foo; # create namespace variable
    set foo "this is ::mynamespace::foo"; # assign value to variable

    proc test {} {
        # First way
        puts "First test: [set [namespace current]::foo]" ;# [namespace current] returns the current namespace
        # Second way
        variable foo; # similar to 'global test', but instead of accessing from the global namespace,
                            # access from the namespace this proc is in
        puts "Second test: $foo"
  }
}
mynamespace::test ;# run proc to test it

There may be others, I'm not sure. I haven't really used namespaces a whole lot.


2007-01-02 jmpb Happy new year! Just came back to this page: nice one!