Chapter 19. Debugging
So far we've explored a lot of techniques and also the syntax to accomplish many goals. Inevitably, however, when you begin writing your own ActionScript, you'll encounter innumerable errors (especially at first when you are still making syntax and conceptual errors). Do not lose heart! Even experienced programmers spend a lot of time debugging (fixing broken code).
It is important that you test your product thoroughly so that you can find the bugs in the first place. This means testing in various browser brands and versions of those brands on all platforms that you intend to support. Test under different flavors of Windows and, if applicable, older versions of the Flash plug-in, which you can find at:
A discussion of testing and quality assurance (QA) is beyond the scope of this book. Suffice to say that you should have a testing and QA process in place and a bug report form on which you can receive reports with sufficient detail (such as the platform, browser version, Flash plug-in version, and reproducible steps) for you to reproduce the error, which is the first step toward fixing it.
Debugging is an essential part of programming and what sets great programmers apart from average ones. Beginners are often happy if a bug that was seen earlier inexplicably disappears. Experienced programmers know that the bug will undoubtedly resurface at the most inopportune time, and although it is intermittent (perhaps especially so), it warrants further investigation. On the other hand, inexperienced programmers tend to shy away from error messages or be unnerved by obvious errors, whereas skilled programmers rely heavily on error messages and know that easily reproducible errors are the easiest kind to fix.
Successful debugging requires logical, disciplined investigative skills and a decent understanding of troubleshooting tools. In this chapter, we'll briefly consider the basics of debugging tools and some general techniques for solving code problems. Remember that debugging is characterized by the systematic challenging of our assumptions. Any given problem is often caused by some other problem upstream (i.e., the disease). We'll use the debugging tools to investigate whether things are in fact operating as designed, and that will lead to an understanding and resolution of the manifest bug (i.e., the symptom).
19.1. Debugging Tools
In addition to these formal debugging tools, Flash also sends error messages to the Output window when a movie is exported or Check Syntax is performed. (Check Syntax is a command listed under the arrow button in the top right of the Actions panel.) Error messages often identify the exact cause of a problem down to the problematic line number in a block of source code. Comprehensive explanations for the various error messages are provided in Macromedia's ActionScript Reference Guide.
Note that not all bugs cause error messages. For example, a calculation that yields the wrong result is a bug even if it doesn't crash your browser. Also note that there are two types of error messages, so-called compile-time error messages that occur when you try to export your scripts and so-called runtime error messages that don't occur until you run your Flash movie and reach the point that causes the error. Compile-time errors indicate some sort of syntax problem such as a missing parenthesis or unclosed quotation. Refer to Part III, "Language Reference", for the exact syntax needed for each command, and refer to Chapter 14, "Lexical Structure", for an explanation of proper ActionScript syntax.
Runtime errors can take a wide variety of forms and may not indicate a problem with the current code under examination but rather may be caused by using the incorrect result of an earlier operation. For example, suppose you try to use the values received back from a loadVariables( ) command sent to a web server. If the Perl script responding to the command didn't supply the correct data in the correct format, you need to correct the Perl script. Your Flash script may be perfectly correct and yet fail because it received incorrect input.
Which brings up an important technique -- defensive programming. You can avoid a lot of errors and potential errors by always checking for potential problematic conditions, which is known as error checking (or sometimes data validation if it pertains to user input). For example, before trying to display the questions of a quiz, you might check that those questions loaded properly. You might also check each question to be sure it's in the correct format for display. If the provided data was improperly entered, you should display an appropriate error message that allows the programmer or the user to take corrective action.
19.1.1. The trace( ) Function
In ActionScript, one of the most effective tools for identifying the source of a bug is also one of the simplest -- the trace( ) function. As we've seen throughout this book, trace( ) sends the value of an expression to the Output window in Test Movie mode. For example, if we add the following code to a movie:
the text "hello world" appears in the Output window. Similarly, here we trace( ) the value of a variable:
var x = 5; trace(x); // Displays 5 in the Output window
Using trace( ) we may check the status of variables, properties, and objects, and we may track the progression of our code. Often by confirming the result of each operation in a script, we can figure out where a problem lies. For example, suppose a function is supposed to return a value but we find, using the trace( ) command, that the return value is undefined (i.e., it prints out as nothing in the Output window). We'd know that we have to examine the function in more detail and make sure that it is properly using a return command to pass back a meaningful value.
19.1.2. The List Variables Command
When a movie is running in Test Movie mode, we can check the value of current variables defined in the movie via the Debug List Variables command. List Variables tells us the name and location of all the variables currently active in our movie and also reports their values. Because functions and movie clips are stored in variables, the List Variables command also shows us the functions and movie clips of a movie.
Example 19-1 shows sample output from List Variables. Notice that the variable rate is shown as declared but undefined. This subtlety is often difficult to detect with trace( ) because trace( ) converts the value undefined to the empty string ("").
Example 19-1. List Variables Sample Output
Level #0: Variable _level0.$version = "WIN 5,0,30,0" Variable _level0.calcDist = [function] Variable _level0.deltaX = 194 Variable _level0.deltaY = 179 Variable _level0.rate = undefined Variable _level0.dist = 264 Movie Clip: Target="_level0.clip1" Movie Clip: Target="_level0.clip2"
Note that both trace( ) and the List Variables command give only a snapshot in time. Often, you'll want to monitor the value of a variable over time or check it repeatedly. The Debugger (discussed later) allows you to track the value of a variable as it changes.
19.1.3. The List Objects Command
The List Objects command produces a catalog of text, shapes, graphics, and movie clips defined in a movie. To execute it, select Debug List Objects while in Test Movie mode. Note that List Objects does not include a list of data objects (instances of a class) in a program; those are reported by List Variables.
Example 19-2 shows some sample output from List Objects. Notice that editable text fields are clearly labeled and that automatically named movie clip instances are revealed (e.g., _level0.instance1).
Example 19-2. List Objects Sample Output
Level #0: Frame=1 Shape: Text: Value = "variables functions clip events startDrag stopDrag Math" Text: Value = "this movie demonstrates a little math, variables, movie clip events" Text: Value = "draggable distance" Text: Value = "calculator" Movie Clip: Frame=1 Target="_level0.instance1" Shape: Text: Value = "distance between clipstotal:horizontal:vertical:" Edit Text: Variable=_level0.dist Text="222" Edit Text: Variable=_level0.deltaX Text="174" Edit Text: Variable=_level0.deltaY Text="138" Movie Clip: Frame=1 Target="_level0.obj1" Shape: Movie Clip: Frame=1 Target="_level0.obj2" Shape:
Again, List Objects provides only a snapshot in time. You need to run it again to get the current value of objects whenever they may have changed.
19.1.4. The Bandwidth Profiler
The Bandwidth Profiler is used to simulate movie download at various modem speeds. Using the Bandwidth Profiler, we may gauge the performance of a movie, test preloading code, and track the position of the main movie's playhead during movie playback. Here's how to turn the Bandwidth Profiler on:
There are many things that can affect Flash performance, such as the assets in use and the rendering demands on the Player. For example, using large bitmaps, rendering complex shapes with many curves, and excessive use of alpha channels can all degrade performance. Asset downloading and rendering times usually dwarf the bandwidth and processor time required for ActionScript to execute. That said, ActionScript is generally much slower than compiled languages such as C.
From an ActionScript perspective, the most time-consuming operations are those that either must wait for data to be uploaded or downloaded or those that are performed repetitively (such as examining a large array).
19.1.5. The Debugger
To enable the Debugger, select Control Debug Movie in the Flash authoring tool (not in Test Movie mode). You may also use the Debugger in a web browser, provided that:
To export a movie with in-browser debugging permitted, select File Publish Settings Flash Debugging Permitted, then optionally provide a password to prevent prying eyes from snooping around your code. To install a debugging Player in your browser, use the installers provided in the /Players/Debug / folder where you installed Flash on your hard drive. To enable debugging while viewing a movie, right-click in Windows (Ctrl-click on Macintosh) on the movie and select Debugger.
The top half of the Debugger (the Display List) shows the movie clip hierarchy of the movie. To inspect the properties and variables of a specific movie clip, select it in the Display List. The bottom half of the Debugger contains three tabs, Properties, Variables, and Watch, which update dynamically to show the properties and variables for the selected clip. To set the value of any property or variable, double-click its value and enter the new data. To single out one or more items for convenient scrutiny, select them in the Properties or Variables tab, then choose Add Watch from the arrow button in the upper-right corner of the Debugger. All "watched" variables are added to the Watch tab (this lets us view variables in different movie clips simultaneously).
For more information about the mechanics of using the Flash Debugger, consult Macromedia's thorough documentation under "Troubleshooting ActionScript" in the ActionScript Reference Guide. If you've lost your Reference Guide, remember that it's available on Macromedia's web site at http://www.macromedia.com/support/flash and also under the Help menu in the Flash authoring tool.
Copyright © 2002 O'Reilly & Associates. All rights reserved.