1 de 9
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
Abstract
Scripting languages are often easier to learn than more formal languages like C++, but this ease of
use can seduce us into use a less desciplined code style which is hard to read and costly to
maintain. By adopting some of the best practices of formal languages, scripters can reduce errors
and shorten development cycles.
Keywords: scripting, fourth-generation languages, programming, code style, HyperTalk, Transcript,
MetaTalk, SuperTalk, Lingo, Hungarian notation, naming conventions.
Contents:
Introduction
General Scripting Techniques
Top-Down Handlers
Clarify Program Flow
Comment Effectively
Comments as Breadcrumbs: What? Bang! Hmmm
Code for Reuse
Code for Speed
Naming Conventions
Variables and Arguments
Handlers and Functions
Objects
Introduction
2014-09-10 14:03
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
At some point in everyone's career, we all write crappy code (except my friend Mark Lucas, but he's in a class by
himself). You know the kind: You go back to it six months later to add new features or better error-checking,
and you have no idea what you were doing. It's "spaghetti code", and it can eat a lot of time as you try to figure
things out all over again. That's where this document comes in.
A few healthy habits can make your code more robust and your workday shorter. While they may require a little
self-discipline at first, if you find these practices useful and adopt them in your daily work they'll become
second-nature and eventually require no extra effort at all.
There are many reasons to use good style practice when writing code, including:
More easily read and understood code
Consistency in a multiple-author environment
Make future enhancement more easily
Turn out code you can be proud to share
Impress the chicks (or dudes, as the case may be)
The tips presented here reflect some of the best practices of many world-class scripters, and we should take a
moment to acknowledge them here:
Michael Silver, Ken Ray, Mark Lucas, and Mark Hanrek are some of the best SuperCard scripters I've known, and
it was while we were sharing code that we discovered that we had each independently developed pretty much
the same code style. The first draft of this document reflected our common interest in SuperTalk, and was
accordingly more limited in scope. It was distributed as part of a panel discussion on scripting techniques at the
SuperCard Developer Conference in 1996, the year SuperCard 2.5 won the Mac Eddy award for Best New
Multimedia Authoring Tool.
Since then this document has been revised many times, expanding its scope to include new tips for other similar
scripting languages. Along the way I've collected valuable tips from a great many programmers, including Scott
Raney, Kevin Miller, Steven McConnell, Jad Santos, and Alex Bronstein. With the things these folks have taught
me, this document should hopefully be useful for scripters who prefer just about any HyperTalk dialect, and a
few others besides.
As you read these tips, you may feel at times that where you code style differs you kinda like it that way. That's
okay. If it works for you, it don't need fixin'.
These are only guidelines, and the more people use them the more easily people will exchange code happily,
solve problems more quickly, spend more time with their families, and create an ever better world.
Having said all that, it is never worthwhile to rewrite existing code simply to conform to these suggestions. Nor
is it worthwhile to stick to a guideline where the function or efficiency of the code is compromised. There is a
fine line between making more maintainable code and more efficient code. It is up to you to decide where that
line is in your own code.
This document is a work in progress. We use it here in the course of teaching and working with contractors, and
accordingly it is always being ammended and enhanced as experience suggests and time permits. If you have
ideas for tips and techniques which you would like to see included here, please email them to me at
scripts@fourthworld.com.
With all that out of the way, here's the beef:
Top-Down Handlers
Some programmers will fight more ardently over whether to list their handlers top-down or bottom-up than
they will over whether to order single-malt or blended. Bad priorities, IMO: pick one code listing method and be
done with it, and spend your brawling time over more important things like whiskey.
Code tells a story, and both top-down and bottom-up tell the same story but each with a different emphasis.
Bottom-up code has core handlers at the top, with the functions that call them below, and system messages at
2 de 9
2014-09-10 14:03
3 de 9
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
the bottom. Top-down puts system messages at the top, the more complex handlers that use them below, with
generalized utiliy routines at the bottom.
Personally, I like to tell a story in the order in which the events occurred, and since events in a script begin with
system messages, it seems a more natural reading to put those first.
Comment Effectively
As a general rule, it's useful to comment any block of code whose functionality is not immediately self-evident.
For example, it's merely distracting to see:
-- Set the cursor to watch:
set the cursor to watch
But it's very helpful to have a brief note like this for more complex blocks:
-- Update each card with the current date:
2014-09-10 14:03
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
Note that the example above also includes a brief description of each handler. This makes handlers stand out
more clearly when skimming, and provides a useful overview as to its purpose.
You can also use comments to separate blocks of code within a handler, like this
on MyHandler
global gMyGlobal
-SomeStatementHere
AnotherStatement
-StatmentForSomethingElse
MoreOfThat
end MyHandler
By breaking code into blocks with comments you can make groups of related statements stand out from the rest
of the code. And by using blank lines only between handlers but not within then, you can skim through the code
more easily.
You'll want to use comments liberally if you're not concerned about script size. SuperCard, HyperCard, and a
few other scripting environments have a 32k limit on the size of a script, so if you run into this limit you make
want to use only important descriptive ones and ditch those used as visual separators to save space.
4 de 9
2014-09-10 14:03
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
--! Bang!
These sections contain issues we know we want to address before shipping the final product, such
as adding error checking or other critical things. A search for "--!" across the code base brings you
right to them:
function GetFileData pFile
--! This will be replaced by Paul's specialized handler in the library
--! he'll deliver for Beta 2:
return url ("file:"&pFile)
end GetFileData
--| Hmmm
These comments are for more general things which may deserve more attention than ordinary
comments but not as critical as What? or Bang! comments.
on SetWindowLoc pWindow
--| RG 060517 Revised to use framework function:
-- set the loc of this stack to the screenLoc
set the loc of this stack to fwAlertLoc()
end SetWindowLoc
5 de 9
2014-09-10 14:03
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
end SumFields
This handler only works if you have three fields using those specific names. You could make it more portable
like this:
put SumFields(fld "Num1", fld "Num2", fld "Num3")
function SumFields
put 0 into tSum
repeat with i = 1 to paramcount()
add param(i) to tSum
end repeat
return tSum
end SumFields
Not only can this handler be used anywhere, by using the param and paramCount functions we can now return
the sum of any number of containers, making it applicable for a great many more uses.
When referring to objects, use names whenever possible. If the name cannot be known or may change, use the
object's ID number. Try to avoid using the ordinal number of the object (e.g., "button 4"), as you may make
changes to the layout which will cause the script to break. Descriptive names also help you understand the
purpose of the object.
Name all objects (cd flds, grcs, wds, &c.). Stay away from using numbers unless your script depends upon that
technique (and even so, you should still name them. I often use names like "Bookmark 1," "Bookmark 2", &c.).
Naming Conventions
Many scripting languages tout their "English-like" syntax as one of their strongest benefits, and of course it is.
But code serves a different purpose than narrative writing, so while readability is important we find that in
production environments code is far more frequently skimmed than read. We don't often read an enitre script to
grasp it's story; if we wrote the code we already know the general story it tells, and if we inherited the code
base some someone else we'll likely read it only once. But in the course of debugging and enhancing the code
base we'll frequently skim for certain elements, specific tokens or patterns, and using naming conventions can
help make the elements you're most likely to be looking for stand out visually from the rest of the code.
In this section we advocate liberal use of what is commonly referred to as Hungarian notation, in honor of the
famous Microsoft programmer Charles Simonyi, who is said to follow this practice obsessively. The value of
Hungarian notation is that it provides a consistent method for determining the use and nature of a given
container by its name alone, without having to look elsewhere in the code to find out where it came from, such
as whether it's global or was passed in as an argument. To varying degrees, this style has been adopted by many
scripters in recent years, as is reflected in the product documentation for Revolution, SuperCard, and others.
6 de 9
2014-09-10 14:03
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
While it can be argued that naming conventions like "Hungarian-lite" make code less readable, it can make the
code more skimmable, which is a far more frequent need over the life cycle of a code base.
Example
Global variable
gMyGlobal
tMyVar
sMyVar
pMyParam
Constant*
kMyNumber
uMyProp
Note about "p": I've had a few readers suggest that "p" should not be used for parameters, and that
scripters using Lingo and AppleScript more commonly use it to designate properties. I've had a
tough time finding published code libraries that use this convention, so if you find any drop me a
note at scriptstyle@fourthworld.com. This document is an ongoing work, and I welcome the
opportunity to keep it up to date as new trends in scripting become evident.
Associative arrays can be local, script-local, global, or passed as a parameter, so to preserve the type
designation arrays are noted with a trailing "A", often in plural form to reflect its status as a collection, e.g.:
gOpenWindowsA
tPasswordsA
pSelectedObjectsA
7 de 9
2014-09-10 14:03
8 de 9
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
When used in libraries, most of the handlers will be for use by other components. But you may have some
handlers which are used only by other routines within the library, not intended for use by others. It can be
helpful to distinguish these "private" handlers, so using a leading underscore ("_") character can help identify
these readily:
on StartTimer
_RunTimer
end StartTimer
on _RunTimer
put the short time into field 1
if "_RunTimer" is not in the pendingMessages then
send "_RunTimer" to me in 100 milliseconds
end if
end _RunTimer
Yes, we know this breaks the rule in the fourth bullet point above, but for a reason: because it's harder to copy
such handler names, it draws extra attention to their more specialized use.
Objects
Object names are usually best left to the specific needs of the program you're working on, but there are some
guidelines which may be useful in some cirumstances:
Fields used as labels can benefit from a prefix of "lbl", making it easy to write repeat loops which skip
over any field with that prefix while setting the values for others.
Stacks, groups, and other objects which are used as templates cloned at runtime can benefit from using
something like "TMPL" as a suffix to make them stand out in object lists.
2014-09-10 14:03
9 de 9
file:///C:/Users/meira/AppData/Roaming/Mozilla/Firefox/Profiles/09k...
Objects which contain behavior scripts can be prefaced with a lower-class "c", to denote their special use
as a sort of class definition as is commonly done in lower-level languages.
2014-09-10 14:03