As you have seen, a watch may be set at any of three levels of scope. This
section considers how to decide which level of scope is best suited to solve a
given problem.
-
Striving to Narrow the Scope
-
Performance Concerns
Striving to Narrow the Scope
The rules governing intelligent declaration of variables largely apply to watches
too. It generally makes sense to limit the scope of a variable, for instance.
If a variable must be used in just one procedure, it should be declared locally
within that procedure; declaring it at a higher level is a needless complication.
In particular, global variables should be used sparingly. Because they can be
modified anywhere in a program, bugs involving global variables are harder to
track down.
In essence, the task of debugging is vastly simplified as the number of places
in which data can be modified diminishes. This rule also applies to watches. Limiting
the number of places in which a Watch expression is evaluated cuts down on distractions
during the debugging process. After all, if you monitor a variable in 100 procedures
when you only need to monitor it in 10, you expend about 10 times more effort
on it than it is worth.
You will recall from the section "Types of Watch Expression"
that you can do three things with a watch:
-
Monitor the value of the Watch expression
-
Break when the Watch expression is True
-
Break when the value of the Watch expression changes
Bearing these options in mind, this discussion begins to focus on some strategies
and constraints regarding watches set on different kinds of variables.
Global Variables
A global variable can be evaluated in a watch at any level of scope. Because
it is available throughout the program, its value can be detected in a watch of
module-level or procedure-level scope as easily as in a global watch.
If you suspect that a global variable is being incorrectly modified, you will
probably want to begin with a global watch. The value of the variable can be changed
anywhere in your program. If you set the watch to break on change or when the
Watch expression is true, however, you will be able to tell which procedure has
modified the value. As you find likely suspects for the bug in question, you may
wish to narrow the scope of your watch, or to set additional watches of more limited
scope.
Module-Level Variables
A module-level variable can be evaluated in a watch at either of two levels:
module level or procedure level. Naturally, a procedure-level watch makes sense
only for procedures found in the same module in which the variable is defined.
The same search pattern suggested for global variables makes sense for module-level
variables. Until you have reason to focus the search on a particular procedure
or set of procedures, you will initially want to set the watch at the highest
scope available. Use watches to trigger a program break to determine which procedure(s)
is the source of your problem.
Local Variables
Obviously, only a procedure-level watch is sensible for local variables. Its
value can be evaluated only in the context of the procedure in which it is defined.
It literally does not exist anywhere else, so there’s no point in looking
for it elsewhere.
The point to limiting the number of places in which your watches are active
is so that you can spend less time looking at meaningless changes. After you have
pinned down the likely sources of a bug, it is only logical to limit the search
to the likely problem areas.
Performance Concerns
Aside from the logical issue, performance concerns are also a motivation to
limit the scope of a watch. Broader watches cause VB to devote more resources
evaluating watch expressions than do watches of more limited scope.
Does the performance degradation produced by a watch that is broader in scope
than necessary really matter? Most of the time, probably not. If you are working
with anything particularly time sensitive, however, the time you may save by limiting
the scope of your watch may make a difference. Even a few milliseconds may be
important to a real-time system, a callback function, or a program relying on
the sequence in which a series of Windows messages is processed.
If you encounter problems along these lines during a debug session in which
you are using watches, try deactivating the watches or limiting their scope before
you decide that you have found more bugs in your program. If the problems go away
after you have changed the watches, it is likely that the watches slowed execution
just enough to cause problems.