Thursday, October 12, 2006

Using ASSERTS with VARTYPE to Test Parameters

I am always looking for ways to bullet-proof my code. One way to do this is to test parameter boundaries and types at the top of programs and methods to ensure that what we are getting is what is expected. Using VARTYPE with ASSERTS is a great way to get started.

PCOUNT(), according the documentation, returns the number of parameters passed to the current program, procedure, or user-defined function. If you are expecting 3 and are passed 2, you can use PCOUNT to handle the problem. PARAMETERS( ) does almost the same thing but can be thrown off by ON KEY LABELS and is reset every time a program, procedure, or user-defined function is called. In either case, relying on PCOUNT or PARAMETERS only gets you half the way there. What if the types are wrong? What if a developer sends in the correct number of parameters but in the wrong order?

VARTYPE() returns the data type of the expression passed to it. It can determine if an object was passed, a Date, or any of the other data types common to the language. If an array is passed, the first element is evaluated. In VFP9 the TYPE() command contains a second argument that you can use to check if a variable is an array. In VFP7, code using VARTYPE() will need to check for an individual element (or elements!). VARTYPE() also supports nulls and can return the data type of a null variable as well. VARTYPE( ) does not require the use of quotation marks around the variable name and is much faster than TYPE(). This makes it preferable in loops or at the top of code that may be run multiple times in succession.

So why use ASSERTS?

ASSERTS are used to verify assumptions you have about the run-time environment. They are great because they are ignored in production (when the exe is run directly from explorer). This means that you can use them in a development environment to bullet-proof your code and not suffer a significant performance hit when the code is shipped to the client (the command doesn't disappear, it is just ignored). If performance is a major concern, stick #DEFINE ASSERT NOTE at the top of the function and your ASSERTS become comments.

There are situations that you will want to use VARTYPE without an ASSERT no matter what (an example would be in a case where the user's action dictates the parameter types or order). I find these scenarios to be rare or at the least, easily identifiable.

Next entry, I'll discuss some methods to boundary check parameters.

No comments: