Guru: Preamble Comments
April 15, 2019 Chris Ringer
Do you remember what you ate for lunch two days ago? If you’re like me, you had to think about it for a minute before answering. Now imagine trying to recall the detailed requirements of a few programs you wrote a year ago so you can modify them for a new project. Or better yet, what if someone else like a retired employee or a traveling contractor coded these programs? At this point you may become very dependent on any comments they left in the code.
It’s been said that any time spent commenting on your code now might save the next developer, perhaps yourself, a great deal of time trying to digest the functionality of that code. For this reason, I’m a big believer in writing thorough preamble comments at the top of the code. These comments describe the program in some detail so the next programmer, which again might be you, can understand the code inception. Preamble comments may be used in any compiled language such as RPG, CL, C#, or in scripted languages such as PHP and JavaScript.
From The Top
The following preamble example, available for download here, is for a Microsoft SQL stored procedure where single line comments begin with a double dash — . Here we go!
-- (C) Copyright Company Name Here 2019
I put a copyright statement at the top of the source code. If the language allows you to embed the copyright into the compiled object, do that instead like this:
RPG: Ctl-Opt COPYRIGHT('(C) Copyright Company Name Here 2019') CL: COPYRIGHT Text('(C) Copyright Company Name Here 2019')
-- Name.......: GetItemBOM_sp
This name comment may seem redundant since a compiled module or program may have the same name. However, some platforms and languages do not link the compiled code to the source code. If an object or script gets renamed, you can still identify the original name of the source code.
-- Purpose....: Returns a result set of BOM child items to caller.
Here state a short purpose of this program.
-- Description: Gets Bill of Materials for an item number. -- Builds a #temporary table and returns that. -- Normally does this for a given Manufacturing -- item and selects the Purchased child items.
State a longer detailed purpose of this program.
-- Author.....: Joe Developer on 1-Jan-2019
If you have questions about this code, you know who to contact.
-- Links......: See the Microsoft Team "Supply Chain Mgmt"
Put a path to any documentation that may exist on network drives, in MS Teams, a URL, anywhere.
-- Project Mgr: Jane Doe
Yes, I will actually list the name of the project manager or product owner in the source code. Again, if you have questions, you know who to contact.
-- Parms_____ In/Out Description___________________________________ -- @iParentItem In The Manufactured parent item. -- @iParentQty In Parent item quanity required. Default is 1. -- Calculates total qty needed for child items. -- @iVendorNum In Optional vendor number. Default is '0001' USA. -- Only return child items from this vendor. -- '*ANY' is any preferred vendor for child item. -- oParentType Out The inventory type of the parent item.
Describe all input and output parameters, including optional parameters and default values.
-- Return Int.: -- 0 = Ok. -- Any negative value means some ERROR occurred: -- -1 = Error (error so no result set returned) -- -9 = Error (no matching rows so no result set)
If a function or method or sub-procedure or stored proc (whatever) returns a value with a RETURN statement, list the possible return values.
-- Exec.......: declare @PMT nchar(1), @int int ; -- exec @int = GetItemBOM_sp 'PART-1',5,'*ANY',@PMT OUT ; -- select @int, @pmt ;
Including a sample call makes testing the program easier for the next developer. Just copy/paste these statements to a command line and run them.
-- Modifications: -- ___Date__ Mod__ Who_______ Description__________ -- 01Jan2019 JD001 Joe Dev. Initial version.
The modification comments shows who did what when and why. It makes sense to add these entries in descending order by date so you don’t have to page down as much in mature programs. If you use version control software that requires check-in comments, like git, you may not need this.
Living On The Edge
What else can you do to help the next developer? Some preamble comments may be language specific or less often used but can still be quite helpful.
-- To Compile.: -- CRTBNDRPG PGM(Library/SCM100) -- SRCFILE(Library/QRPGLESRC) SRCMBR(SCM100) -- DFTACTGRP(*NO) ACTGRP(*CALLER) -- DBGVIEW(*LIST) REPLACE(*YES) -- USRPRF(*OWNER) AUT(*EXCLUDE) -- -- CHGOBJOWN OBJ(Library/SCM100) OBJTYPE(*PGM) -- NEWOWN(DBUSER)
Sometimes I must study a *PGM object in production to determine how it was compiled. For this reason, I just include the compile command in the source code. Don’t include options that are already natively embedded in the source code such as a Ctl-Opt specification. Again, just copy/paste this comment to compile unless your change managements software compiles source code for you.
-- Called by..: RPG program SCM100 or manually in a session.
You may be able to use tools like Abstract or Hawkeye to identify what other programs call this one. If this is a utility called by many processes, literally state “By many processes” so the next developer will know this is a critical program that needs thoroughly debugged. Or perhaps this is an ad hoc program only run from the command line. Or perhaps this is a program called from another system or from the job scheduler. This particular MS stored proc returns a Bill of Materials to an RPG client and is not referenced anywhere else on that SQL server.
-- Run time...: 5 minutes
Knowing the expected run time of a batch job is very helpful for troubleshooting. If the program has been running for 30 minutes and the expected run time is five minutes, you can suspect there is a problem.
-- Warning....: Upstream process *must* exec SetSite -- to set the site_ref or a result set -- may *not* be returned.
Document any potential “gotchas” lurking out there.
-- Cloned ....: INV123
If you cloned another program to create this one, include the name of the cloned source code so if a bug is found in this code, the other source may be checked for that same bug as well. And this comment creates a nice linked list of source code for historical purposes.
-- Peer Review: No
Indicate here if a change to this source code requires a peer review by another developer. If you are on a scrum team using mob programming, then you won’t need this comment since every line of code is reviewed as it is written.
-- Deprecated.: Yes - Use MyOtherProc instead
If this program is being phased out and replaced, list the name of the newer program, preferably under the copyright comment.
-- To Debug...: No special instructions
If debugging this code has any setup or tricks then include those instructions here.
-- To Restart.: Just call it again
If this is batch job, include restart instructions if the job abends.
The End Zone
I truly believe every minute spent documenting code now will save the next developer 10 minutes trying to comprehend it. But at some point, it may become too much so the extent of those comments is a judgment call. You need to decide which preamble comments are required and which ones are optional. If you clone source code, make sure you update all the preamble comments or the comments may not reflect the newer source code and become confusing. In closing, I hope you enjoyed these suggestions and encourage you to adopt some of them in your coding.
Even if you use something like git that requires check-in comments, I think it’s a good idea to also put change-history comments into the code. If you move to something other change management tool in the future, you’d have to remember to recover the change history and then you’d likely have to add it back into the source so the history wasn’t lost.
Hi Barbara, I concur and that is what I do. A check-in/commit comment to a repo may be for a group of changes across many source members and that comment is usually just one or two sentences, a short summary. Thanks.
Chris
Be nice to see a follow-up to this article describing how the use of specific commenting styles coupled with a tool such as RPGDOC (https://sourceforge.net/projects/rpgdoc/) or Paul Touhy’s RPGLEDOC (http://systemideveloper.com/downloadRPGLEDOC.html) can increase the value of comments. Also commenting in an appropriate position (immediately prior to the definition) works well with RDi because the text will be displayed when you hover over the item where it is used in the program.
Excellent piece.
Like the author, I am a big believer in internal program documentation.
IMO, two things are a must when developer documents their effort (in preamble!) – and quite too often are missed .
1. BUSINESS purpose of the module.
2. Details of how is called (manual, online, where from, batch, soft call, web, stored procedure, never ending process, etc, etc, etc.)
Living On The Edge
What else can you do to help the next developer?
How about being able to see your program comments AND your program source code and data in real-time as they execute in real-time.?
The Real-Time Program Audit (RTPA) IBM i software allows you to do exactlly that., while providing a real-time security camera audit log of everything that is executing inside the computer that has been audit enabled by IBM?
Why does not IBM provide that incredible capability to all IBM i customers?