450 lines
15 KiB
Plaintext
450 lines
15 KiB
Plaintext
-----------------------------------
|
|
xBase Identifier Naming Conventions
|
|
|
|
-or-
|
|
|
|
H U N G
|
|
Hungarian types without the arian
|
|
-----------------------------------
|
|
Robert A. DiFalco 71610,1705
|
|
-----------------------------------
|
|
Revision 1.02
|
|
-----------------------------------
|
|
|
|
|
|
Let me start off by stating that these are only my opinions on naming
|
|
conventions for xBase programming. In my opinion these methods are
|
|
extensible to C, ASM, BASIC and just about any other programming
|
|
language. It looks very similar to Hungarian notation as outlined by
|
|
Charles Simonyi of Microsoft Corporation. Don't be fooled, however, this is
|
|
much different. I find it more intuitive and logical though that may
|
|
pertain only to my thinking. Also, this naming convention was not
|
|
thought up by myself but rather is a bastardization of the Clipper
|
|
recomended naming conventions and conventions used by many of the
|
|
programmers I know. Charles Simonyi's original paper can be found in MSSYS
|
|
forum on CIS in library 10 under the name of HNGRN.ZIP and should be read
|
|
for reference.
|
|
|
|
|
|
These conventions take in the same factors as outlined by Charles Simonyi
|
|
for creating names in a program. The factors listed below are directly
|
|
quoted from his monograph.
|
|
|
|
Begin quote:
|
|
|
|
1. Mnemonic value - so that the programmer can remember the name.
|
|
|
|
2. Suggestive value - so that others can read the code easily.
|
|
|
|
3. "Consistency" - this is often viewed as an aesthetic idea, yet it
|
|
also has to do with the information efficiency of the
|
|
program text. Roughly speaking, we want similar names
|
|
for similar quantities.
|
|
|
|
4. Speed of decision- we cannot spend too much time pondering the name of a
|
|
single quantity, nor is there time for typing and
|
|
editing extremly long variable names.
|
|
|
|
End quote:
|
|
|
|
In xBase, our variable names have even a more pressing reason for short
|
|
identifiers since we only have 10 characters to work with. To alleviate
|
|
using needless characters, we will use lowerUpper combinations instead of
|
|
dividing underscores.
|
|
|
|
|
|
Procedure/Function Naming conventions
|
|
=====================================
|
|
Procedures and Functions will be heretofore called "Functions". Function
|
|
names will not be "typed" as variables. As xBase and languages in general
|
|
head towards object oriented approaches it is important to allow our
|
|
Functions to return multiple types. This negates the approach of typing
|
|
Functions by return variable type. Instead we will apply a "loose" set of
|
|
rules to Functions. Native language functions will be in all lowercase
|
|
while 3rd party or "home grown" functions will be mixed case beginning
|
|
with a single Capital letter.
|
|
|
|
1. Functions will start with a capital letter followed by lower case
|
|
letters thus distinguishing them from variables. If the Function name
|
|
can be better expressed by two or three identifiers an UpperLower
|
|
combination will be used rather than underscores to delimit identifiers.
|
|
Consider the following Examples:
|
|
|
|
ClrSet() - Sets colors
|
|
SaveGets() - Saves active get list
|
|
PrnScr() - Prints the screen
|
|
GetPass() - Gets a password
|
|
Choose() - Menu of items to "choose" from
|
|
|
|
2. Conversion Functions will start with the value they take and end with
|
|
converted value separated by the number 2. Some examples would be as
|
|
follows:
|
|
|
|
Str2Arr() - Changes a string to an array.
|
|
Hex2Dec() - Changes a Hex string into a decimal numeric.
|
|
Clr2Attr() - Changes a color string to an integer attribute.
|
|
Dbf2Arr() - Loads a DBF into an array.
|
|
|
|
3. Where possible, use standard qualifiers as outlined in the section
|
|
dedicated to "Variable Naming Conventions". A few examples follow.
|
|
|
|
Clr - Color
|
|
Scr - Screen
|
|
Crs - Cursor
|
|
Max - Maximum value
|
|
Min - Minimum value
|
|
Str - String
|
|
Fld - Field
|
|
Prn - Print
|
|
|
|
4. Where possible, express the @function of procedure in less than three
|
|
qualifiers ( names ). Refer to the examples given for Rule 1.
|
|
|
|
5. The keywords PROCEDURE, FUNCTION and RETURN shall be in all uppercase.
|
|
|
|
FUNCTION SayStr( cMsg, cClr )
|
|
local cSavClr := setcolor( cClr )
|
|
|
|
? cMsg
|
|
setcolor( cSavClr )
|
|
|
|
RETURN NIL
|
|
|
|
Language native functions shall be typed in all lowercase to delineate them
|
|
from non-native functions as in the above call to setcolor(). The exception
|
|
to this is Object oriented export instance variables which will employ the
|
|
lowerUpper notation standard as used by OOP languages such as SmallTalk.
|
|
|
|
oBrowse:addColumn( oColumn )
|
|
^ ^
|
|
| Upper case First letter
|
|
Lower case first tag name
|
|
|
|
|
|
DBF and Field related Punctuation Conventions
|
|
=============================================
|
|
There are some rules noteworthy for DBF, NTX, ALIAS and FIELD operations to
|
|
delineate them from Functions and Variables. FIELD names will NOT be typed
|
|
by a lowercase type identifier as with Variables.
|
|
|
|
1. Database and Index files, as well as Field names will always be expressed
|
|
in capital letters. As xBase languages main point of existence is the
|
|
manipulation of DataFiles, this will make them stand out against
|
|
variables and other qualifiers.
|
|
|
|
2. Where possible they will use the same standard qualifiers used for
|
|
Variables and Functions. See the examples for Rule 3 of
|
|
"Procedure/Function Naming Conventions".
|
|
|
|
3. Fields will be referenced by an ALIAS. Consider the following.
|
|
|
|
HACCT->ACCNUM
|
|
HCONST->PASSWORD
|
|
HCONST->COMPANY
|
|
|
|
4. Variables referencing Fields will have the same name as the Field with
|
|
the addition of the HUNG type prefix.
|
|
|
|
cFName := HCUST->FNAME
|
|
cLName := HCUST->LNAME
|
|
cAddr := HCUST->ADDR
|
|
nAge := HCUST->AGE
|
|
lActive := HCUST->ACTIVE
|
|
nBalance := HLOAN->BALANCE
|
|
|
|
( Please note that the storage operators ( "=" ) are lined up for easy
|
|
reading giving a table appearance. )
|
|
|
|
5. With regard to DBF file names, data, index or otherwise they should
|
|
all begin with a common prefix and that prefix is similar to the
|
|
name.
|
|
|
|
This insures that I have few naming conflicts with other systems
|
|
that may reside on the computer and just about guarantees I can
|
|
separate my files out if they get placed into a common subdirectory.
|
|
|
|
6. Index filenames should reflect the file that they belong to but
|
|
should not attempt to indicate what the index expression is. A
|
|
much cleaner routine results when index files are simply numbered.
|
|
|
|
HACCTS.DBF ---> HACCTS1.NTX
|
|
HACCTS2.NTX
|
|
HACCTS3.NTX
|
|
|
|
Internally the only information I am required to keep is the index key
|
|
in an array and all indexes can be rebuilt in the order of their
|
|
respective suffix number.
|
|
|
|
|
|
Command Punctuation Conventions
|
|
===============================
|
|
This area of my HUNG naming conventions will probably meet with the most
|
|
opposition. User Defined Commands will use descriptive names as outlined in
|
|
"Procedure/Function Naming Conventions". User Defined or not, Commands
|
|
will have one Rule.
|
|
|
|
1. All Commands will be typed with lower case letters.
|
|
|
|
The reasons for this are simple. This will delineate commands from
|
|
variables, functions and DBF elements. Consider the following examples.
|
|
|
|
FUNCTION CmdExample
|
|
|
|
use HCUST new
|
|
set index to HCUST1, HCUST2, HCUST3
|
|
|
|
cLName := "DiFalco"
|
|
|
|
seek cLName
|
|
|
|
HCUST->AGE := 28
|
|
HCUST->ACTIVE := .t.
|
|
HCUST->LNAME := cLName
|
|
|
|
close HCUST
|
|
|
|
RETURN NIL
|
|
|
|
( Please take note that in replace statements we also line up the "with"
|
|
portion of the command as we do storage operators. )
|
|
|
|
|
|
Variable Naming Conventions
|
|
===========================
|
|
This is the heart of a well HUNG system. Variable names must give the
|
|
most amount of information possible in its name while using the minimum
|
|
number of characters possible.
|
|
|
|
Variables will have one mandatory character, the "Type Prefix". But will
|
|
usually have a combination of tags that will in most cases appear in this
|
|
order.
|
|
|
|
1. A single lower case variable defining its type as returned by a Type()
|
|
function called a "Type Prefix".
|
|
|
|
2. An Optional state called a "State Qualifier"
|
|
|
|
3. A "Standard Qualifier Tag".
|
|
|
|
4. An Optional "Pointer Reference".
|
|
|
|
|
|
Type Prefixes
|
|
-------------
|
|
a - Array
|
|
b - Code Block
|
|
c - Character
|
|
d - Date
|
|
h - Handle
|
|
l - Logical
|
|
n - Numeric ( nX is optional where X is the number of decimal places )
|
|
o - Object
|
|
v - having a Variable type as in a macro or changing value
|
|
|
|
For temporary variables of distinct type or pointers this single prefix can
|
|
be used by itself. Consider this example.
|
|
|
|
for n := 1 to nFldMax
|
|
aFldName % [n] := Field( n )
|
|
next
|
|
|
|
|
|
Sample "State Qualifiers"
|
|
-------------------------
|
|
New - a New state
|
|
Sav - a Saved state
|
|
Tem - a Temporary state
|
|
|
|
|
|
Sample "Standard Qualifier" tags
|
|
--------------------------------
|
|
Attr - Attribute
|
|
Ar - Array
|
|
Clr - Color
|
|
Crs - Cursor
|
|
Dbf - of or pertaining to a DBF
|
|
F - First as in cFName
|
|
File - Any type of file
|
|
Fld - Field
|
|
L - Last as in cLName
|
|
Msg - Message
|
|
Name - a name
|
|
Ntx - of or pertaining to an Index ( or Idx|Mdx|Ndx etc. )
|
|
Rec - Record Number
|
|
Ret - Return value ( lRet := .f. )
|
|
Scr - Screen
|
|
Str - String
|
|
T - Top
|
|
L - Left
|
|
B - Bottom
|
|
R - Right
|
|
Row - Row
|
|
Col - Column
|
|
X - Row
|
|
Y - Column
|
|
|
|
Please note that Standard Qualifiers can be used in combinations as in the
|
|
following examples.
|
|
|
|
nTRow - Top Row
|
|
cFName - First name
|
|
cDbfFile - a Database file
|
|
cNtxFile - an Index File
|
|
|
|
Sample "Pointer References"
|
|
---------------------------
|
|
1,2,3 - State pointer references as in cSavClr1, cSavClr2, etc.
|
|
Max - Strict upper limit as in nFldMax, maximum number of Fields
|
|
Min - Strict lower limit as in nRecMin, minimum number of Records
|
|
|
|
|
|
These lists are to serve as samples and building blocks. They can and
|
|
should be added to. Lets look at a few examples of the conventions at work.
|
|
This should dispel the myth that notation conventions cannot be applied to
|
|
variables with a 10 character maximum length.
|
|
|
|
|
|
Poorly HUNG and well HUNG Examples
|
|
----------------------------------
|
|
|
|
WRONG RIGHT WHY
|
|
========== ========== ===============================================
|
|
nFldNum nFld Number is indicated by the Type Prefix making the
|
|
word Num redundant and a needless use of character
|
|
space.
|
|
Count n n serves as a temporary count index. Count has no
|
|
Type Prefix.
|
|
Last_Name cLName This is one of the most horrendous mistakes. First
|
|
we do not specify the variable type. Second we
|
|
needlessly spell out LAST and worst of all we use
|
|
up a precious character by using and underscore
|
|
instead of using the upperLower combination.
|
|
SaveScreenA cSavScr1 No Type Prefix, needless use of characters. The
|
|
SaveScreenB cSavScr2 alphabetical reference is allowable though I prefer
|
|
SaveScreenC cSavScr3 to use a numeric reference.
|
|
|
|
ColorStr cClr No Type Prefix. Needless use of characters. Colors
|
|
are indicated as a string by the Type Prefix.
|
|
nRecNo nRec The use of "No" is redundant.
|
|
|
|
PrintReset cPrnReset Also could have been shortened to cPrnRst.
|
|
|
|
MessageStr cMsg These are starting to become obvious, don't you
|
|
think?
|
|
|
|
|
|
Lets take a look at how a function can be rewritten using the HUNG
|
|
conventions for xBase. Examine this Function closely. Variables, Commands
|
|
and Function name do not conform to "Well Hung" coding techniques. This
|
|
Function has been written in Clipper and is actually a Sample program
|
|
slightly modified. Those of you that do not understand Clipper should still
|
|
be able to see the benefits.
|
|
|
|
|
|
/***
|
|
* LISTASARRY( <list_str>, <delimiter> ) --> str_array
|
|
* Convert a delimited string to an array
|
|
*
|
|
*/
|
|
FUNCTION LISTASARRAY( list_str, delimiter )
|
|
LOCAL position
|
|
LOCAL str_array := {} // Define an empty array to return
|
|
|
|
IF delimiter = NIL
|
|
delimiter := ","
|
|
ENDIF
|
|
DO WHILE !EMPTY(position := AT(delimiter, list_str))
|
|
* ..... Add a new element
|
|
AADD(str_array, SUBSTR(list_str, 1, position - 1))
|
|
list_str := SUBSTR(list_str, position + 1)
|
|
ENDDO
|
|
AADD( str_array, list_str ) // Add final element
|
|
RETURN str_array // Return the array
|
|
|
|
|
|
Now take a look at the properely formatted equivelant.
|
|
|
|
/***
|
|
* Str2Arr( <cStr>, <cDelim> ) --> aRet
|
|
* Convert a delimited string to an array
|
|
*
|
|
*/
|
|
FUNCTION Str2Arr( cStr, cDelim )
|
|
local nPos
|
|
local aRet := {} // Define an empty array
|
|
// fill and return.
|
|
if cDelim == NIL
|
|
cDelim := ","
|
|
endif
|
|
|
|
do while !empty( nPos := at( cDelim, cStr ) )
|
|
* ..... Add a new element
|
|
aadd( aRet, substr( cStr, 1, nPos - 1 ) )
|
|
cStr := substr( cStr, nPos + 1 )
|
|
|
|
enddo
|
|
|
|
aadd( aRet, cStr ) // Add final element
|
|
|
|
RETURN aRet // Return the array
|
|
|
|
|
|
DEBUGGING EXAMPLES
|
|
==================
|
|
Hung Notation allows us to readily see errors in our routines that might
|
|
otherwise take quite a bit of hunting around.
|
|
|
|
Why does this snippet of code bomb?
|
|
|
|
* Begin Fragment
|
|
|
|
IF type == "EDIT"
|
|
LOOP
|
|
ENDIF
|
|
|
|
DO WHILE MONTH == 9
|
|
|
|
* End Fragment
|
|
|
|
Are you able to tell me? Ofcourse not, we are not given enough information.
|
|
If we had used Hung Notation, however, the error would have been obvious.
|
|
|
|
* Begin Fragment
|
|
|
|
if nType == "EDIT"
|
|
loop
|
|
endif
|
|
|
|
do while cMonth == 9
|
|
|
|
* End Fragment
|
|
|
|
Ahh, now we are getting somewhere. The program has TWO errors. It is trying
|
|
to evaluate the numeric <nType> against the string "EDIT". We know <nType>
|
|
is a numeric because of its Type Prefix. Look a little farther and we can
|
|
see the exact reverse of the error with the character <cMonth> being
|
|
evaluated against a numeric constant 9.
|
|
|
|
|
|
This paper is by no means comprehensive but should still be able to guide
|
|
a programmer towards a standard Typing Convention for xBase. I realize that
|
|
this is not for everyone but find it to be a productive method for myself.
|
|
If you have any questions or additions please respond to me on the DBA
|
|
forum at my COMPUSERVE ID# listed at the top of these Txt file.
|
|
|
|
|
|
Robert A. Difalco
|
|
Fresh Technologies
|
|
|
|
Special Thanks to Tom Leylan and Matt Maier
|
|
|
|
|
|
Revision History:
|
|
|
|
11/30/90 1.00 Original Draft
|
|
12/05/90 1.01 Changed Database Standards
|
|
12/10/90 1.02 Added some Clipper specific examples
|
|
12/13/90 1.03 Added special handling for exported instance variables
|
|
|
|
|