PDF In-Depth

Tips for Writing Reliable Code

August 23, 2001

Advertisement
Advertisement
 

Bug prevention planning pays off

There's no getting around the fact that if you write code (whether it's in a scripting language like JavaScript or a high-level language like C or Pascal), you're going to encounter bugs. That's a fact of life. But ideally, you'd like to keep encounters of the creepy-crawly kind to a minimum, because every minute spent chasing a bug is a minute you could have spent doing something more profitable. Bug prevention should thus be high on your list of priorities.

I've found that there are certain work habits and practices that, if followed religiously, tend to make me produce better (more reliable, less buggy) code, almost against my will. I'd like to share some of those habits and practices with you now.

Variable Naming

It's tempting to make up variable names as you go, following no particular pattern, but if you write enough code you'll soon come to the realization that a little time spent thinking up intelligent names for variables can make debugging a lot easier and can even prevent bugs from cropping up in the first place.

Put some thought into choosing meaningful names for your variables. A descriptive name like 'TotalNumberOfItems', while seemingly long and unsightly, is actually preferable to a short but cryptic name, such as 'num' or 'n'. Why? Because you don't have to scan nearby code to figure out what the variable does. If the variable is named descriptively, it's even possible that somebody who has never seen your code before (i.e., your successor after you get promoted) might be able to figure out how the code works just by reading the variable names.

An important part of making variable names work in your favor is being consistent. Some programmers follow a discipline of using prefixes on variable names, such as 'n' at the beginning of numeric variable names (like nTotal, nMaximum, etc.), 'b' at the beginning of Booleans, 's' on the front of strings, 'g' on the front of variables with global scope, 'k' on the front of constants, etc. Consistency of this kind may seem obsessive-compulsive at first, but down the road you'll start to appreciate the way it makes your code more "self-evident."

It should go without saying that in an object-oriented language like JavaScript, you can often see gains in legibiltiy and even code structure by following a hierarchical naming scheme involving parent and child objects. For example, if you create a "customer" object, then attach a "name" property to it (with properties like "first" and "last"), address properties, etc., you end up dealing with customer.name.first, customer.name.last, customer.address.street, etc., instead of a zillion unrelated-looking variable names. An array of customer objects then becomes easy to deal with, whereas juggling separate arrays of 'firstname', 'lastname', and 'treetaddress' can be overwhelming after a while.

The Uninitialized Variable

Watch out for uninitialized variables. If you try to use a variable that has no value (in a comparison statement, for example), you will generate an error. Assigning a safe "dummy value" to every variable at the time it's created is a good habit to get into since it will prevent this kind of error. What if you're not sure whether the variable has been declared before? Check its type with typeof().

if (typeof(myVariable) == 'undefined')
   ;  // don't use it!

The typeof() function will return 'undefined' if the variable has not been declared.

Brevity Is No Substitute for Legibility

Always prefer legibility over elegance or conciseness. If an expression can be more clearly expressed in three JavaScript statements than in one, by all means use three statements! You're not going to win any awards for brevity, and in many cases, execution speed is the same (or nearly so) with two or even three statements as it is with one. For example, a nested call is rarely, if ever, faster than the same statements "unrolled."

// Concise (but unreadable):
x = Math.abs(Math.floor(4 * Math.sin(180 * Math.PI * r)));

// More readable, and just as fast-executing:
x = Math.sin(180 * Math.PI * r);
x *= 4;
x = Math.floor(x);
x = Math.abs(x);

There may be one or two extra register loads going on in the second version (involving four expressions), but you can be pretty sure the JavaScript interpreter is pushing just as many values on the stack in either case. Rolling a bunch of calls into one line of gibberish is no concession to speed. Don't be fooled.

Cut and Paste Are Your Friends

A good heuristic for avoiding typos is: Don't type any more than necessary! Use Cut and Paste when editing code, to save on keystrokes. I'm such a klutz that if I have to type a long variable name three times in a row, it's a pretty good bet I'll mess up at least one keystroke somewhere along the line. So I try to cut down on typing, and bugs, by cutting and pasting variable names. And guess what? It works!

Typos are a major source of trouble when you're dealing with nested function calls and conditions checks, because it's not clear (after a while) whether you've balanced all your parentheses. Likewise, on long string literals, you're likely to break a line with a carriage return without remembering to introduce a continuation marker (backslash). And in long strings, don't forget to check for nested quotation marks. Alternate the use of single and double quotation marks when nesting quotes. Otherwise, you'll make a string terminate early, generating an error.

Incidentally, don't hesitate to break long lines of code into multiple lines. You don't have to use a backslash (continuation marker) as long as you put your carriage returns between variable names or operators. For example, I often do things like:

var choice = app.popUpMenu('Typeface:',
   'Times-Roman',
   'Times-Bold',
   'Times-Italic',
   'Times-BoldItalic',
   'Helvetica',
//  ...  etc.
    );

Breaking a long statement like this into multiple lines makes code more readable and makes typos stand out more, I find.

Comment Your Code

Code that is sparsely commented is hard to maintain. I'm sure you've heard the story about the programmer who, returning to some code he'd written just two weeks before, nevertheless spent three and a half hours stepping through the code in a debugger (trying to understand the program's structure) before coming to the conclusion that the code's purpose was so obvious, it didn't need commenting.

Today, you may think your code doesn't need commenting. Tomorrow, you will realize the folly of yesterday's decision.

Comments are easy to add to JavaScript:

// this is a comment

/* as is this */

There's something of an art to writing good comments, as with other aspects of programming. Just labelling an exclusive-OR operation "XOR" doesn't explain the purpose of that particular line of code. Think hard about what the code is doing, then come up with a comment that you (or someone else) might find helpful during a debugging session. Some lines of code truly need no explanation. Others may require multiline comments. If you need six lines of commentary to explain one line of code, use six lines. I'll say it again: Brevity is often the enemy of legibility.

Granularity

Make your code granular by "factoring out" complex operations into short functions. Generally speaking, it's easier to understand and debug a hundred one-line functions than it is to understand and debug one 100-line function. Of course, it's possible to go too far in the direction of "factoring." But my experience has been that most beginning programmers (which I still am, in many ways, after 12 years) are prone to write functions that do too much and take up too many lines of code. Break it down! Keep functions simple. With any luck, you'll achieve some code reuse (and not have to write so much code on down the line).

Back It Up

Backing up your code as you work is difficult to remember to do sometimes. But you're risking disaster if you don't make frequent backups. A rule of thumb that has never let me down is: Always have working code. What that means is, as soon as something "works," back it up; and before starting work on a project that's halfway done, back it up. You always should be able to revert to working code if you accidentally paint yourself into a corner during a "bad day."

Test-Fly Pieces of Code

This is one of my all-time favorite tips. Create a small, blank, one-page PDF document and name it "eval.pdf." Add two form fields to it: a button, and a multiline text field. Call the text field "Code." Don't attach any scripts to it. Call the button "Evaluate" and add a script to the mouse-up event:

   eval(this.getField('Code').value);  // evaluate Code

What this line of code does is take whatever you've typed into the Code field and try to run it as JavaScript. The eval() function is a core JavaScript method that takes a string argument, representing code, and presents it to the runtime interpreter, as if to say "Here, run this." If you type "app.beep(0)" in the Code window, for example, hitting the Evaluate button should make your computer's speaker beep.

Use the Code window to test snippets of code before you place them inside scripts in another PDF document. Whenever you're not sure how something works, dummy up a function in the Code window of your form and Evaluate it. Use the app.alert() method to display the result to the screen. You won't believe how much time this trick will save you during development.

Get to Top-Level Scripts Fast

Another real timesaver is to put a button on the any form-in-progress that takes you straight to the document-level scripts in your form. I don't know about you, but I get tired of click-click-clicking through menus and submenus to get to Acrobat's top-level code window (Tools:Forms:Document JavaScripts...). To get there faster, use Acrobat's Links tool to create a link on your page somewhere, then in the "Type:" popup menu, select "Execute Menu Item." Use the dialog that comes up to navigate to the Tools:Forms:Document JavaScripts command. When you're finished, you'll have a link onscreen that, with one click, takes you straight into the document-level scripts area.

Note that you can also create a link that takes you straight to Page Open and Page Closed action scripts.

And remember: After a particularly rough coding session, take a long break. Man does not live by JavaScript alone. Wife DEFINITELY doesn't.

PDF In-Depth Free Product Trials Ubiquitous PDF

Debenu Quick PDF Library

Get products to market faster with this amazing PDF developer SDK. Over 900 functions and an equally...

Download free demo

Back to the past, 15 years ago! Open Publish 2002

Looking back to 2002, it's amazing how much of the prediction became a reality. Take a read and see what you think!

September 14, 2017
Platinum Sponsor





Search Planet PDF
more searching options...
Planet PDF Newsletter
Most Popular Articles
Featured Product

Debenu PDF Aerialist

The ultimate plug-in for Adobe Acrobat. Advanced splitting, merging, stamping, bookmarking, and link control. Take Acrobat to the next level.

Features

Adding a PDF Stamp Comment

OK, so you want to stamp your document. Maybe you need to give reviewers some advice about the document's status or sensitivity. This tip from author Ted Padova demonstrates how to add stamps with the Stamp Tool along with related comments.