What's wrong with Globals?
mwieder at ahsoftware.net
Sat Mar 31 00:11:13 CDT 2007
What's wrong with globals?
Normally I don't trot out my globals tirade because it upsets people,
but since you asked...
<flame suit on>
Globals are what I usually think of as the way people start out using
variables until they learn better ways. It's a way of avoiding
learning some "proper" techniques of programming: decoupling,
narrowing scope, things that make your code better.
<flame suit off>
That said, Chipp Walters has hipped me to some very clever ways of
using globals in a rev environment that would actually be rather
clumsy doing any other way (relying on persistence even after a stack
has been removed from memory).
So, in addition to the fine job Jim Ault has done explaining globals,
I'd like to add:
1. Global variables can be changed from multiple spots in your code.
That value you just put into a global variable may have just gotten
overwritten by some other object (a card script, a timer, etc) and is
not the value you expect. The whole reason local variables exist is to
restrict variable scope to prevent them getting stepped on.
2. As Jim pointed out, globals stick around in memory and you can't
tell if they're there or not - the act of checking creates them.
As a corollary, many modern languages do garbage collection
periodically, in which unused variables are removed from memory to
reclaim space. The use of globals which are expected to be persistent
can cause problems translating from one computer language to another.
3. Trying to edit a script to change a global into a local variable is
messy. The compiler complains because the global is still in memory
from the last compilation. You have to go to the message box first and
global xyz;delete global xyz
and then you can change the xyz declaration in your script to local.
This is especially messy if you have the global defined in several
scripts (which I assume is why you made a global in the first place).
If you absolutely have to use a global, it's best to stick to the
convention of a "g" prefix (gMyGlobal) so that 1) if you decide to
change it to a local later on you can just drop the "g" globally
(haha) and 2) you can be sure in reading your code when you're
using a global and when you're using a local.
4. There's almost always a better approach than using a global
variable. Passing a parameter to a function rather than filling in a
global variable and retrieving it comes to mind, as does using custom
properties. Or just rethinking the code that called for a global in
the first place.
5. If you have more than a few objects, it starts getting a bit fuzzy
as to who's using a given global. If you want to change or delete a
global, do you actually have clear in your head all the places in your
stack where it's used? Can you stuff a new value into it and not
affect something 20 cards down the line? If you rename a global, can
you remember all the places that use it? And how they interact?
6. Using global variables couples objects, stacks, scripts together
very tightly in a way that message- or parameter-passing does not.
7. Just because a global is declared in multiple places doesn't
guarantee that it will be used for the same purpose. Worst case
scenario: "global gTemp" as a temporary storage between scripts will
almost invariably cause problems. It may be used to store a
temperature variable to be recovered by another script, which then
places a result string into it to be retrieved by a third script. This
can cause no end of debugging nightmares.
I don't use global variables myself if I can at all avoid it. In all
the time I've been using rev I think I have maybe a handful of global
variables sprinkled through my code, and usually just because I was
too lazy to do things right. I've almost always regretted putting
things into global variables and had to spend more time fixing them up
I do use get and set routines sometimes for variables that have to
have a life outside of their home scripts. I think it's just one step
above the use of global vars, but at least it affords a little bit of
control over when a global var gets changed and makes it a bit easier
to debug. I can always put a breakpoint into the setter routine to see
who's changing it:
on PutSomeVar pValue
-- could put a breakpoint here
put pValue into someVar
mwieder at ahsoftware.net
More information about the use-livecode