|Perl: the Markov chain saw|
Pass by reference vs globalsby tilly (Archbishop)
|on Mar 20, 2001 at 02:41 UTC||Need Help??|
The claim about changing things by reference being similar to globals is one I understand but only halfway agree on. What is similar is action at a distance. However while globals by definition create that, modifying by reference can either increase or decrease.
Remember that the goal of programming well is to do the job, within your set constraints, while maximizing the maintainability of the code. From the point of view of getting something simple done, globals are always easiest. However they also open you to global side-effects, which increases the amount the programmer needs to keep in mind. In general if you have n sections of code, any of which can interact with any other, that is order n*n interactions to keep in mind. Which is bad.
However many people hear this and say, Oh, I won't use globals. But I will use a reference to something that I pass around everywhere and set and change as I need. Voila! No more globals!
But while you have removed the label, you have not changed the problem very much. The data is still being shared everywhere, it is just being shared by a different mechanism. You still have action at a distance. You still have the maintainability issue.
This is the sense in which I agree with dkubb's criticism.
However I only halfway agree. As a counter example in object oriented programming you everywhere pass around a reference to something, and you can modify it by reference anywhere. Yet good programmers who avoid globals are quite willing to use OO programming. What is different?
The difference is that OO puts the code that requests from the data structure together with the code that places it. Therefore all of the information about mechanics, internal counters, etc is encapsulated in a relatively small section of code. While requests may come from many places for many reasons, the mechanics of how to do it no longer suffer as much from action at a distance.
Now in practice that might not be true. And certainly it takes experience to produce good OO designs. But that is the principle.
But I should qualify all of this with one observation. Perl as a language has a ton of global variables. Good programmers avoid them. However, despite having a ton of globals, Perl is a rather effective language. How does that work?
IMHO what is going on is simple. The maintainance problem that globals cause is due to the increase in how much you need to keep in mind. Globals are almost always useful in terms of getting things working, but they bite you down the road. Therefore there is a balance between the theoretical evil and the practical utility. Every global is another thing to be constantly kept in mind, and only applies when working on that code. Therefore the cost of learning Perl's globals can be amortized across many programs. While the cost of keeping a global in your scripts can only be amortized across that script. So the tradeoff comes at a different point.
Even so I find that for me, Perl has gone too far. Most of the special variables in perlvar I do not use. My brain is too small to keep them in mind. At least they have names that cannot be confused with regular variables, so if someone else uses one I can look it up. But I don't use them. I prefer to use that mental energy for general principles, known bugs, and remembering my grocery list. :-)