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 conditioned 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 reference and use the return value for error codes (usually T/F).

To pass a variable by reference, use @ like this:


It sounds complicated, but its not. Here is an example:
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