Home Web Design Programming Fairlight CMI Soap Box Downloads Links Biography About... Site Map

The Holmes Page Replace a Public Variable With a Set/Get Function

CA-Clipper Opportunities Tips and Tricks Networking Internal Errors Source Code CA-VO


Public variables are inefficient and unprotected, just like private variables. (See Converting to CA-Clipper 5 for a discussion of private variables.) 
However, public variables serve a very useful purpose: to store a value that is accessible throughout the entire program. 
The following is a sample of source code that uses a public variable:
01  procedure Main ( )
02     public cUserName
04     cUserName := LogOn()  // Determine the User's name.
05     ? cUserName           // Display it.
06     F1()                  // Call the offending function.
07     ? cUserName           // ERROR!
08                           // "Variable does not exist".
09  return
11  function F1 ( )
12     cUserName := 0        // Bad data - should not allow.
13     release cUserName     // Eeek! It gone!
14  return
The purpose of the public variable in this code is to allow access to the User's logon name throughout the program. The problem with the public variable is that it is not protected from programming "errors" like the ones on lines 12 and 13. 
At line 12, the number 0 is assigned to the cUserName variable. This is not an error as far as CA-Clipper is concerned, because CA-Clipper is not a strongly-typed language. However, an alarm should go off in your mind because the name of the variable, cUserName, indicates that only character values should be assigned to the variable. This assumption is based on the use of Hungarian Notation. Some other part of the program will probably fail when it encounters a numeric value where it expects a character. 
Line 13 is also a problem because the release command completely removes the variable from memory, thus subsequent references to the variable will fail. 
What is needed is a way to prevent the assignment of invalid data, and a way to protect the value from being released. This is accomplished by creating a set/get function.
01  procedure Main ( )
02     UserName(LogOn())     // Determine the User's name.
03     ? UserName()          // Display it.
04     F1()                  // Call the offending function.
05     ? UserName()          // Display it. No damage done.
06  return
08  function F1 ( )
09     UserName(0)           // Bad data - will be ignored.
10     release cUserName     // No effect.
11  return
13  function UserName ( pcNewName )
14     static scName:=''
15     local cOldName:=scName
17     if valtype(pcNewName) == 'C'
18        scName := pcNewName
19     endif
20  return cOldName
In this code the UserName() function manages all accesses to the internal scName variable (defined on line 14), which acts like a buffer. The function allows you to assign to the buffer (set) and it returns the previous value of the buffer (get), which is why it is called a set/get function. 
At line 9, attempting to assign 0 to the value is ignored, because the code at line 17 only allows the assignment if the parameter to the function is a character. Further processing could be performed here, for example to convert the parameter to uppercase, or to remove all leading and trailing spaces. Here is a replacement for line 18 that does these things:
18        scName := upper(alltrim(pcNewName)) 
The code at line 10 (release cUserName) serves no purpose and does no harm, because there is no longer a variable called cUserName.

Home Web Design Programming Fairlight CMI Soap Box Downloads Links Biography About... Site Map

Site Map Send comments about this site to Greg at gregh@ghservices.com
All pages copyright © 1996-1999 GH Services™   Created 1997/06/06   Last updated 1999/09/30
All trademarks contained herein are the property of their respective owners