6 |
The LA Fox Developer Newsletter
May 1995
Candy Machine
(Con't from page 5)
usually with a corrupted database!
I don’t know if Steve was able to get the candy
machines changed. But he did change Microsoft’s
coding standards in a simple, easy to use way, and
he eliminated that kind of bug from ever occuring
again. He changed a coding style that
encouraged
bugs, to a style that
prevented
bugs.
The root cause of this kind of problem, according to
Steve, is having a function mix return values and
error codes. If a function usually returns character
data, but will occasionally return numeric or logical
error codes, it will be bug-prone. Forever.
The fix is just as simple as the problem. The error
code is one output from the function, and the return
value is another. The solution is to re-write your
function to return the error code separately from the
return value.
Think about it for a second. We’ve all been condi-
tioned to think that functions only have one return
value. Functions written in the “normal” way only
have one return value, that is, they can change only
one value in the calling routine.
A function that uses a variable passed by reference
can change the
referenced
variable
in the calling
routine,
as well as the normal return value of the
function itself. A function that uses variables passed
by reference can change more than one value in the
calling routine. Its as though you could say
RETURN(a,b) and get multiple return values from
one function.
To use Steve’s technique in FoxPro, pass a variable
to hold the value you want to your function by
refer-
ence
and use the return value for error codes (usu-
ally T/F).
To pass a variable by reference, use
@
like this:
It sounds complicated, but its not. Here is an ex-
ample:
If we were to write getcsystem the normal way, just
using one return value, how would we indicate that
something was not in the database? We could
return an empty or blank string, but that is a valid
condition in this particular system. We could return
a logical .F. or a valid string, but then the caller must
examine the variable type of the return code, a real
bother to code. We could write 2 functions, one to
check if the value exists, and another to return the
value, again a pretty clumsy solution.
Should you design every function using a variable
passed by reference? No, many functions have no
error returns possible, and it would not be worth the
time and
extra
code to first initialize a variable and
then pass it by reference. But, for functions that
can
have an error return, it is worth the time and bother
to do it in a bug-reducing way.
Steve suggested that you design functions that “lead
programmers to write correct code
the first time.
Don’t use confusing dual-purpose return values
-
each output should represent exactly one
data
type.”
(Con't, page 9)
Page 6
|
6 |