Version 0 of Variable versus a Global Array

Updated 2003-09-15 03:28:24

Keith Vetter 2003-09-14 : Everyone knows that global variables are bad, and that putting your variables into their own namespaces via the variable command is better. Variable is a more modern, oo'ish interface that scales better and leads to better encapsulation, etc.

Sorry, I don't agree.

Granted, unrestrained use of global variables can be bad, but I claim that with the proper use of global you can get most of the benefits that variable seems to provide plus a few more benefits as well.

My opinion comes from my experience in writing and maintaining a 10,000 line tcl program called Klimb (sorry, no link, the web site is down). The first half of the program I wrote just using global variables. Then I refactored much of the code, adding namespaces and namespace variables. All new development over the past year has been using namespaces and variables, but that may change due to my experience I'll relate here.

First off, the main benefits of variable are encapsulation and not polluting the global namespace, which also helps in avoiding name collisions when the code is used by others.

But I can get exactly these benefits from global variables if I put all the variables of a module into one global array. The array encapsulates all my data and, likewise, there's only one name that you need to worry about collisions for, e.g. ::mymodule(var) versus ::mymodule::var. As an aside, namespaces help but don't really solve the name collision problem; for example, in A Symmetric Doodler the (non-namespace) name symdoodle'move probably has the same probability of collision as the (namespace) name symdoodle::move would have.

A global array has further benefits. Encapsulation is in fact tighter w/ an array. It's much easier saving and restoring a modules state with array get and set. My rc files are often not much more than a prettied up copy of the output of array get (and to read them I just source them). Emulating the (very desirable I think) feature of class instantiation (w/ each instance having separate variables) is easier w/ arrays.

Granted, you could argue why not combine both techniques and get the best of both worlds. You can and I often do just that.

But where variable drives me crazy is in debugging. I debug by running my app from a console window, then I walk code by pasting in the code from the procedure I'm interested in debugging. This has served me well for over 10 years of tcl coding. But namespace variables break this, since these variables are not directly accessible from the console's default namespace. You either have to tweak each variable to use its fully qualified name, or to upvar the variables into the global namespace.

Arts and crafts of Tcl-Tk programming