Blog
iDevelop

Advertisement

« Time Flies When You're Having Fun: AS/400 Marks 20th Anniversary | Main | Another Prototype Question: How to /Copy? »

July 08, 2008

To /Copy or Not to /Copy--That is the Question (for Prototypes)

We hope by now that most of you have come to understand the value of using prototypes for all your calls, whether to subprocedures or programs. If not, check out our i5 EXTRA article. But we still find ourselves repeatedly debating the value of using /Copy to get your prototypes into the program vs. just a block copy (CC) in the editor from one member to another--or worse yet, manually recode it each time. So this week, we decided to address the question of "Why /Copy prototypes?"

We think using /Copy is a very important habit to get into for three reasons:

  1. If you have coded a Procedure Interface for the program or procedure in question, the compiler will have checked the prototype for you. So using /Copy means you're using code that you know is correct. That's why the compiler insists on having the prototype code in the source member when you compile a subprocedure or a program that uses a PI (Procedure Interface) in place of a *Entry PList. Of course, if the called code is not written in RPG IV (e.g., a system API or an old RPG/400 program or a CL program) then the compiler isn't going to check it. But even in those exceptional cases, once one programmer in the shop has written the prototype for it, why should everyone else figure it out and write it over and over again?
  2. The person who is in the best position to know what the parameter list for the program or procedure should look like is the one who wrote that code. This includes information such as which parameters can be considered optional. That person should be the one who writes the prototype and puts in into a member to be copied into both the called and calling source members. The easiest way to get that prototype into the callers is to /Copy it.
  3. Perhaps the best reason of all is because of what is likely happen when a programmer gets a compile error when making a prototyped call. If the programmer either re-codes or block copies a prototype into his/her program and gets a compile error on the call statement (e.g., passed the wrong number of  parameters or the wrong data type), the programmer has two options to fix that problem--either change the parameters on the call statement or change the prototype. In reasons 1 and 2 above, we established that changing the prototype is almost never the right answer! Putting the prototype in a separate source member means they have to work a bit harder to do the wrong thing! Hopefully before doing that, the programmer will think twice about whether they should be changing the prototype that someone else wrote in another source member. It makes it just a little easier to do the right thing and figure out how to change their call statement to match the prototype and not the other way around.

So why not /Copy? One of the most common arguments we hear against using /Copy ((for prototypes)) is that it means the programmer has to go look in two members to find out what's happening. Our response is that it isn't true if you're using a modern editor. RSE shows prototypes and descriptions of all of the parameters in the Outline View. Usually this gives you the information you need. If you still need to see the actual prototype code (i.e., to see the documentation for the parameters) then RSE makes it very simple to open the /Copy member quickly.

So those are our arguments for /Copy. We suspect we don't even need to invite those of you who disagree to send in your comments--you probably already have them mentally prepared!

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83545a5d153ef00e5538e85bb8833

Listed below are links to weblogs that reference To /Copy or Not to /Copy--That is the Question (for Prototypes):

Comments

/COPY is an old, old friend from back in the Auto Report days. One thing that would have been excellent to see is a recommendation for a naming convention. I use one borrowed from David Morris, long ago. I put my prototypes in QPROTOSRC and give the member the same name as the member containing the PI code.

If I have 3 date procedures, I might put them in QRPGLESRC mbr(DATES). The prototypes all go in QPROTOSRC mbr(DATES), and the service program is called DATES. That way it's simple to know what everything is named.

I'm a fan of putting the prototypes in the same source member as the subprocedures, and surrounding the non-prototype code with /IF NOT DEFINED and /ENDIF.

Some think its convoluted but I think it makes maintenance easier and the prototypes reliable because a change to the prototype when in the same source member as the subprocedure necessarily requires a recompile (using MKS Implementer) while a change to a prototype member does not.

/Copy works great until someone deletes the source. This can render all /Copy directives useless. Why would anyone delete a source file? It happens (Fat Finger Syndrome or just your basic ID10T error) to be of programmers (the difference between 4 and 14 is one digit).

Steve - I'm hoping your tongue was firmly in your cheek when you wrote that comment but ...

If this is a real problem, then I have to assume that source programs are also in the same danger of being deleted. In what way would a /COPY member be different? How do you recover when program is "accidentally" deleted? If the answer is "from the backups" then surely the answer is the same for /COPY members?

In shops where this is a real problem (although frankly if this is happening they have many other much bigger problems) a simple solution is to always compile with the Debug option *LIST (or *ALL). That way you can recover the source from the PGM object, recover any /COPY members and indeed recover the specifications for any files used - after all they have probably been deleted as well!

Hi Buck,

It seems like I've used COPY forever. In fact I think the only time I could not use it was when programming plugboards! In every other language I have used from COBOL to C to assembler to Java to PHP to ... no one would ever think of doing anything but use a copy for common code and definitions. I am always amazed at the number of RPGers that do not use them.

I've said before that I often wish that CC had never been added to SEU. If you could only copy one line at a time maybe people would use /COPY more often!

As to naming, I also often use the QPROTOSRC convention - but I also try to use a PR in the naming of the member - although I can see the logic behind your approach.

The vast, vast majority of RPG programs (*PGM, that is) that I write are unlikely to ever be called by another RPG program. Instead, they're called by a CL, by Apache, or by menu software. In those environments, the prototypes are not useful! To me, putting the prototypes for these programs into a separate member is extremely cumbersome. I don't want to have to maintain twice as many source members!

By contrast, when I write a service program (*SRVPGM -- which is what I use for any code I expect to call from multiple places) I find copy books full of prototypes to be invaluable, and wouldn't attempt service programs without them.

Just another perspective.

"The vast, vast majority of RPG programs (*PGM, that is) that I write are unlikely to ever be called by another RPG program. Instead, they're called by a CL, by Apache, or by menu software. In those environments, the prototypes are not useful!"

Agreed 100% Scott - If the *PGM is not called from RPG I would not use a /COPY for the prototype.

However, I think you may be in the minority in this case. The majority of the customers we deal with have extensive program "chains" and in those cases the prototype is invaluable. Also remember that few people make such extensive use of Service Programs as you do - consequently functions that we would assign to a service program are often free-standing *PGM objects.

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been saved. Comments are moderated and will not appear until approved by the author. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Comments are moderated, and will not appear until the author has approved them.