Updated 2013-01-18 15:27:48 by pooryorick

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!