Page 2 of 3
Globals and locals
Programming using nothing but global variables is fine until you start writing large programs and using functions or other types of module.
Once you break a large program down into functions or methods then the pay off is that you can write each as if it was a completely separate program.
Well you can as long as every variable that you use isn't a global variable. If you have to worry about what names you can use for a variable while writing a function, because the name might have already been used in another function, then it is as bad as writing the program in one chunk.
For example, most programmers tend to use i and j for loop indices - to understand why you need to go back to the days of Fortran. If every variable is global then it's only a matter of time before an i or a j used in one function collides with their use in another function. This sort of name collision is the reason we don't like global variables.
The solution is to use local variables. Local variables, are confined in scope to the function or method that declares them. For example, if you define Local A in one function and Local A in another function then the A in the first function has nothing to do with the A in the second function- they are different variables that just happen to share the same name.
If you are building a modular program then all of the variables within each module should be Local. How then do the modules communicate?
The answer is only by passing data using parameters. Parameters are another story and to avoid getting side tracked I will assume that everyone knows what a parameter is and how they work. Parameters have a lot of devious traps waiting to get the careless programmer, but for the purpose of talking about variables these will also be ignored.
So what are global variables for if every variable in a module should be local to that module and if data is to be passed using parameters? One answer is that global variables aren't for anything they are just a leftover from the days when we didn't know better.
An alternative answer is that passing every item of data that a module needs is boring, error prone and results in procedure calls the length of War and Peace.
Rather than pass every variable to a module it makes good sense to define the major items of data as global and allow every program to access them using the same name. After all if you have an array called TOTALS it is usually called TOTALS in all of the procedures that use it even if it is passed in as a parameter! In this sense the array is being treated as if it was a global variable even though it is local to each procedure.
The difficulty with this approach is how to draw the dividing line between what should be global and local. At its extreme it results in everything that might be passed as a parameter being declared as global and every procedure call consists of just the name of the procedure!
In other words, using local variables results in long parameter lists and using global variable results in no parameter lists. Both approaches have their problems but today the emphasis falls on the need to decouple the modules that make up a program and hence local is always better than global.
Objects and namespaces
However you shouldn't write off the global variable because it has new life in the form of object oriented programing. In this paradigm the objects are the fundamental modular division used to divide a program up into manageable chunks. Each object keeps its variables local and even private i.e. inaccessible from outside of the code that makes up the object however in most designs the main objects themselves have global names.
This is the reason we have had to introduce the idea of namespaces. A name is now promoted to something much more involved. Now you can assign a very long and complicated name which you hope will not collide with other similar names. For example:
might be the name of a class that you would otherwise have just named myclass1. Obviously there is a lot less chance of collision if you use the long name than if you use the short name - but the long name is a bit of a nuisance to type. The solution is the introduction of a namespace - basically a default prefix added to all variables. That is if you are working in the namespace:
then when you use the name myclass1 it is assumed you mean:
Of course if you want to use myclass1 in a different name space then you can do so but only if you enter the complete qualified name of the class you really want to use. For example:
is a different class from the one you created. To make things easier various looser name space rules are generally used. For example, if you use an unqualified name then each name space is searched until a fully qualified name (FQN) is found. If more than one FQN is found that matches then the collision is brought to the programmer's notice and a fully or partly qualified name has to be used to resolve the ambiguity.
Put simply name spaces were introduced to control global names.
You may have noticed that this entire discussion has been in terms of class rather than object. The same ideas apply, however, to objects, i.e. instances of classes. Your project has a name space associated with it and when you create a new object it too has a fully qualified name given by appending the name space. Of course it's up to you to keep everything under control and avoid name collisions within your own small naming universe.
Name spaces aren't perfect but they are the only way we have of keeping global names under control.