What's wrong with Globals?
J. Landman Gay
jacque at hyperactivesw.com
Fri Mar 30 22:35:24 CDT 2007
Joe Lewis Wilkins wrote:
> Please enlighten me. With HC I never really had any problem using
> Globals pretty extensively. I know all of the "old" adverse thoughts and
> how it was felt to be bad programming practice; and, perhaps, before we
> could have some pretty long vars, maybe it was tough coming up with
> names that didn't create conflicts, but I think we're past all of that
> now. So... why is using Custom Properties any better than using globals.
Like Richard, I use variables and custom properties for different
reasons. If data needs to be saved permanently with the stack (like a
set of user prefs, for example) custom properties are perfect. Rev
stores your preferences this way. For data that is only used during the
current session, I think it is preferable to use variables.
But I avoid globals in general, and prefer script-local variables
instead. Globals clutter up the name space and the variable watcher,
they are hard to keep track of, and there can be naming conflicts with
other stacks. Mostly it's the cluttter I don't like. I've translated a
lot of HC stacks that make me cringe from global overload. I've also
noticed that many novice HC authors used globals simply because they
didn't know how to pass parameters. That's easy to fix.
I once worked on a large HC conversion that used globals all over the
place, there must have been more than a hundred of them. This was often
necessary in HC because there wasn't any other way to do certain things,
but by the time your variable watcher fills up with that many globals
you can hardly keep track of any of them. In this particular stack, I
was able to change the globals to script-locals in almost every case,
and reduced the number of globals down to a small handful. I usually
only employ globals for data that needs to be frequently accessed across
stacks or objects. For infrequent access I sometimes use custom
properties intead; it depends.
A script-local variable acts just like a global, but with a more limited
scope. It only "belongs" to the script that contains it, rather than
being accessible from anywhere. When that script isn't being executed,
the variable is out of the way. It is easier to keep track of these
variables because they only appear in a single script; they don't
populate the variable watcher anywhere else.
For example, how many times in HC did you have to do something like this:
put true into gBoolean
if gBoolean = true then doThingThree
put false into gBoolean
Though these handlers are in the same script, HC requires a global
variable to retain the value of gBoolean between handler executions.
With Rev, a script local variable can do this instead. Just pop the
variable up at the top of the script and it is available to any handler
in that script:
local sBoolean -- this is the only declaration you need
put true into sBoolean
if sBoolean = true then doThingThree
put false into sBoolean
Outside of this script, the variable is not available and stays out of
the way. However, the script itself retains the value of the variable
for the entire session; you don't need to reset it between handler
executions. I really like script local variables. They are like
Custom properties are a different animal. They provide permanent storage
because they are saved with the stack, but you can also use them as
temporary storage if you want to. The down side to using them as
temporary, session-specific storage is that when the stack closes (or
opens) you have to remember to initialize them to empty. With
script-local variables, that isn't an issue because, like any variable,
script-locals disappear when the engine quits.
Custom properties take slightly longer to access than either global or
script-local variables. The increased access time is small, so in most
cases it's moot. But if speed is an issue or you have a lot of data to
retrieve frequently, use variables instead of custom properties.
Custom properties, like variables, are created automatically whenever
you first reference them:
set the cUser of this cd to "joe"
creates a custom property of the card called "cUser", if it doesn't
already exist. The value of the "cUser" custom property is "joe". Now
whenever you need to get that value, you can retrieve it:
put the cUser of this cd into tUserName
Now the variable "tUserName" contains "joe". The custom property will be
saved with the stack. We used to use hidden fields for this stuff in HC.
Custom properties are much better; they are like infinite hidden field
space with some additional enhancements besides -- and you don't have to
clutter up your stack with invisible objects. Remember the stacks that
used to store data at the top of scripts? The ones with big "DO NOT MOVE
THIS DATA" comments around them? (Apple shipped the calendar stack with
one of those.) Those lines of script would have been in custom
properties, if HC had had them.
Custom properties can also be stored in custom property sets, which you
can create at will. Custom property sets are arrays with keys and values
-- basically just a group of related properties. You can have the same
keys in different sets if you want; for example, you could have a custom
property set called "English" and another one called "French". Each
array could have the same keys; perhaps each key would be a field name.
The values in the keys of each set would be different though -- the
English set would store the English names for the fields, and the French
set would store them in that language.
It then becomes very easy to change all the field labels to the language
of choice when the stack opens. You simply set the customPropertySet of
the stack to the language you want, and set each label field to the
value of the matching key in the array.
I generally use custom properties for different things than I use
variables. They can be somewhat interchangeable, and I do that
sometimes, but in general I like variables for session use and
properties for permanent storage.
Jacqueline Landman Gay | jacque at hyperactivesw.com
HyperActive Software | http://www.hyperactivesw.com
More information about the use-livecode