Bob,
10 lines is a good rule to live by. There are some exceptions like the
Initialization routine or large CASE structures that have many options. But
the problem you run into if you don't restrict your lines is you end up
doing more than one thing. Most of the Pick programming that I've run
across has the subroutines going on and on and on.
Making your subroutines short and precise is a good exercise in good
programming practices. In Object Oriented Programming we are taught that
more than 3 lines are too much.
Here is an sample program:
PROGRAM RUN.GUIDE
* DAG Consulting -- WWW.DAGCONSULTING.COM
* David A. Green -- 5/2/01
*
*
EQUATE TRUE TO 1, FALSE TO 0
EQUATE CLR TO @(-1)
!
DEBUG.FLAG = TRUE
!
GOSUB INIT
GOSUB PRINT.SCREEN
GOSUB OPEN.FILES
!
IF NOT(ABORT.FLAG) THEN
LOOP
GOSUB SELECT.RECORDS
IF TOT.CNT THEN
LOOP
READNEXT VOC.KEY ELSE DONE.FLAG = TRUE
UNTIL DONE.FLAG DO
GOSUB READ.REC
IF OK.FLAG THEN GOSUB OPEN.FILE
IF OK.FLAG THEN GOSUB LOCKFILE
IF OK.FLAG THEN GOSUB PROCESS.REC
IF OK.FLAG THEN FILEUNLOCK F.FILE
REPEAT
END
GOSUB END.LOOP.LOGIC
WHILE LATER DO REPEAT
END
!
GOSUB PRINT.TOTALS
!
STOP
!
END.LOOP.LOGIC:
END.CNT += 1
IF END.CNT > 10 THEN ;* Give up after 10 trys, write the
remainder to a list.
PRINT "Max tries exceeded, remainder written to list RUN.GUIDE"
WRITELIST LATER ON "RUN.GUIDE"
LATER = ""
END ELSE
IF LATER THEN
SLEEP 10
FORMLIST LATER
END
END
RETURN
!
SELECT.RECORDS:
IF SYSTEM(11) THEN
TOT.CNT = SYSTEM(11)
END ELSE
CMD = "SSELECT ":FNAME:" WITH F1 = 'F'"
PERFORM CMD CAPTURING BUFF
TOT.CNT = @SYSTEM.RETURN.CODE
END
RETURN
!
READ.REC:
READ VOC.REC FROM F.VOC, VOC.KEY THEN
OK.FLAG = TRUE
END ELSE
WAR.CNT += 1
OK.FLAG = FALSE
PRINT "Warning: File ":DQUOTE(VOC.KEY):" NOT found in VOC!"
END
RETURN
!
OPEN.FILE:
OPEN VOC.KEY TO F.FILE ELSE
ERR.CNT += 1
OK.FLAG = FALSE
PRINT "Can't open ":DQUOTE(VOC.KEY):"!"
END
RETURN
!
LOCKFILE:
OK.FLAG = TRUE
FILELOCK F.FILE LOCKED GOSUB LOCKED.FILE
RETURN
!
LOCKED.FILE:
OK.FLAG = FALSE
LATER<-1> = VOC.KEY
PRINT "Will try ":DQUOTE(VOC.KEY):" later, file in use."
RETURN
!
CHECK.CRITERIA:
SELECT.OK = TRUE
*
* Add Selection Criteria Here if Necessary
* IF VOC.Dict.Name = "" THEN SELECT.OK = FALSE
*
RETURN
!
PROCESS.REC:
PRO.CNT += 1
PRINT VOC.KEY:"..."
CMD = "!guide ":VOC.KEY
GOSUB DO.CMD
CMD = RENAME.CMD:" GUIDE_ADVICE.LIS ":VOC.KEY:"_GUIDE_ADVICE.LIS"
GOSUB DO.OS.CMD
CMD = RENAME.CMD:" GUIDE_ERRORS.LIS ":VOC.KEY:"_GUIDE_ERRORS.LIS"
GOSUB DO.OS.CMD
CMD = RENAME.CMD:" GUIDE_STATS.LIS ":VOC.KEY:"_GUIDE_STATS.LIS"
GOSUB DO.OS.CMD
CMD = RENAME.CMD:" GUIDE_FIXUP.DAT ":VOC.KEY:"_GUIDE_FIXUP.DAT"
GOSUB DO.OS.CMD
RETURN
!
DO.CMD:
PERFORM CMD CAPTURING BUFF
RETURN
!
DO.OS.CMD:
PCPERFORM CMD CAPTURING BUFF
RETURN
!
INIT:
VOC.REC = ""
ABORT.FLAG = FALSE
DONE.FLAG = FALSE
FNAME = "VOC"
TITLE = "Running guide"
TOT.CNT = 0
PRO.CNT = 0
ERR.CNT = 0
WAR.CNT = 0
LATER = ""
END.CNT = 0
*
** OS Specific Settings
*
OS.TYPE = SYSTEM(33)
BEGIN CASE
CASE OS.TYPE = "UNIX" ; RENAME.CMD = "mv" ; FILE.SEP = "/"
CASE OS.TYPE = "Windows NT" ; RENAME.CMD = "RENAME" ; FILE.SEP = "\"
CASE 1 ; RENAME.CMD = "mv" ; FILE.SEP = "/"
END CASE
RETURN
!
PRINT.SCREEN:
PRINT CLR:TITLE
RETURN
!
OPEN.FILES:
ONAME = "VOC" ; OPEN '', ONAME TO F.VOC ELSE GOSUB OPEN.ERROR
RETURN
!
OPEN.ERROR:
PRINT "Can't open ":DQUOTE(ONAME)
ABORT.FLAG = TRUE
RETURN
!
PRINT.TOTALS:
COL.WIDTH = LEN(TOT.CNT); COL.FMT = COL.WIDTH:"R"
PRINT
PRINT "Total Records : ":TOT.CNT COL.FMT
PRINT "Total Processed : ":PRO.CNT COL.FMT
PRINT "Total Errors : ":ERR.CNT COL.FMT
PRINT "Total Warnings : ":WAR.CNT COL.FMT
RETURN
!
END
-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Bob Woodward
Sent: Tuesday, September 27, 2005 1:30 PM
To: [email protected]
Subject: RE: [U2] Good Programming Practice Question.........
I agree with Kevin, specifically for the reasons he mentions, but I
actually prefer using the alpha-numeric format like S3000.GET.CUSTNAME:
where the "S" designates it's an internal subroutine, "3000" is the
numeric position value that Kevin talks about, and "GET.CUSTNAME" so
every place that I call the subroutine from, I know what I'm looking to
do in that subroutine. I also put the colon ":" so when I want to
actually go to that subroutine in the editor, I can. The numeric
portion is in relation to the whole program, not just the "S" portion.
This keeps me from accidentally doing a A3000 instead of an S3000.
I do have to disagree with the statement of 10-line subroutines, though.
Limit them to one function, okay, but limit the number of lines? Not
even as a guideline in my list of standards.
BobW
> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:owner-u2-
> [EMAIL PROTECTED] On Behalf Of Kevin King
> Sent: Tuesday, September 27, 2005 1:04 PM
> To: [email protected]
> Subject: RE: [U2] Good Programming Practice Question.........
>
> And here's where the conflict begins. When looking through a big
> program, I much prefer numeric labels in order with comments vs.
> alphanumeric labels. With numeric labels in order you find 1800 and
> if you're looking for 2000 you know to look farther down, 1000, go up.
> With alpha labels if you find SELECT.FILE and are looking for
> UPDATE.FILES, you have nothing but experience to know whether to look
> up or down from there.
>
> Numeric labels are good. Not ordering or commenting them is bad. And
> not putting comments around all labels to make them more easily
> distinguished from the rest of the program is near unforgiveable.
>
> -K
>
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] On Behalf Of Allen E.
> Elwood
> Sent: Tuesday, September 27, 2005 12:40 PM
> To: [email protected]
> Subject: RE: [U2] Good Programming Practice Question.........
>
> My addition to this would be to use alphanumeric labels, and to *have*
> a main calling section. A main calling section that looks like:
>
> GOSUB OPEN.AND.INIT
> GOSUB SELECT.FILE
> GOSUB PRE-PROCESS.VALIDITY.CHECKS
> GOSUB PRINT.INVOICES
> GOSUB UPDATE.FILES
>
> Looks so much better and is so easier to figure out than
>
> GOSUB 100
> a bunch of statements
> a bunch of statements
> a bunch of statements
> GOSUB 1250
> a bunch of statements
> a bunch of statements
> a bunch of statements
> GOSUB 1375
> a bunch of statements
> a bunch of statements
> a bunch of statements
> GOSUB 4000
> a bunch of statements
> a bunch of statements
> a bunch of statements
> GOSUB 9755
> a bunch of statements
> a bunch of statements
> a bunch of statements
>
> IMNSHO - *=aee=*
>
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] Behalf Of George Gallen
> Sent: Tuesday, September 27, 2005 12:12
> To: [email protected]
> Subject: RE: [U2] Good Programming Practice Question.........
>
>
> Also, how about a change log at the top of the program
> that lists, who, when and what/why a change was made.
>
> add to that a short description as to what the function
> of the program is for.
>
> * this program does .....
> *
> *
> * date who changes made
> * date who changes made
> ********************************************
> *
>
> George
>
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] Behalf Of Dianne
> Ackerman
> Sent: Tuesday, September 27, 2005 2:57 PM
> To: [email protected]
> Subject: Re: [U2] Good Programming Practice Question.........
>
>
> I like these and would add another one - Add comments to
> tricky-looking code!
> -Dianne
>
> David A. Green wrote:
> -------
> u2-users mailing list
> [email protected]
> To unsubscribe please visit http://listserver.u2ug.org/
> -------
> u2-users mailing list
> [email protected]
> To unsubscribe please visit http://listserver.u2ug.org/
>
> --
> No virus found in this incoming message.
> Checked by AVG Anti-Virus.
> Version: 7.0.344 / Virus Database: 267.11.7/112 - Release Date:
> 9/26/2005
> -------
> u2-users mailing list
> [email protected]
> To unsubscribe please visit http://listserver.u2ug.org/
-------
u2-users mailing list
[email protected]
To unsubscribe please visit http://listserver.u2ug.org/
-------
u2-users mailing list
[email protected]
To unsubscribe please visit http://listserver.u2ug.org/