× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.




Just another few suggestions for newcomers to ILE:

1. Adding the module name to the procedure

Adding the name of the module ,that exports the procedure, to the
procedure name is helpful for analyzing the source code.

Example:

Module MOD1 contains the following statement:

dateRtn = PopupCalender_show();

The (standard) prototype of PopupCalender_show() looks like this:

D PopupCalendar_show...
D PI D
D initDate D value options(*nopass)

What to you think which modules exports procedure PopupCalender_show()?

The output of command "DSPMOD MODULE(MOD1) DETAIL(*IMPORT)" is useless:

Module . . . . . . . . . . . . : WSDL2R01
Library . . . . . . . . . . : RADDATZ
Detail . . . . . . . . . . . . : *IMPORT
Module attribute . . . . . . . : RPGLE

Imported (unresolved) symbols:

Symbol Name Symbol Type ARGOPT
POPUPCALENDAR_SHOW PROCEDURE *NO

But you can get more valuable information from DSPMOD with the prototype
modified like this:

D PopupCalendar_show...
D PI D
D extproc('DATEUTIL_+
D PopupCalendar_show+
D ')
D initDate D value options(*nopass)

The module using the popup calendar does not need to be changed. It still
looks like this:

dateRtn = PopupCalender_show();

But DSPMOD shows the following information, now:

Module . . . . . . . . . . . . : WSDL2R01
Library . . . . . . . . . . : RADDATZ
Detail . . . . . . . . . . . . : *IMPORT
Module attribute . . . . . . . : RPGLE

Imported (unresolved) symbols:

Symbol Name Symbol Type ARGOPT
DATEUTIL_PopupCalendar_show PROCEDURE *NO


2. Using "Camel Case" names

Using "Camel Case" or "Pascal Case" names incredibly improves reading
DUMPs and call stacks.

Call stack with camel case procedure names:

Procedure
_QRNP_PEP_WSDL2R01
WSDL2R01
main
WSDL2R97_XMLSAXParser_run
XML_Parse
XML_ParseBuffer
prologInitProcessor
prologProcessor
doProlog
contentProcessor
doContent
startElement
WSDL2R05_WSDLParser_cbSaxSt >


The same call stack with all upper case names:

PROCEDURE
_QRNP_PEP_WSDL2R01
WSDL2R01
MAIN
WSDL2R97_XMLSAXPARSER_RUN
XML_PARSE
XML_PARSEBUFFER
PROLOGINITPROCESSOR
PROLOGPROCESSOR
DOPROLOG
CONTENTPROCESSOR
DOCONTENT
STARTELEMENT
WSDL2R05_WSDLPARSER_CBSAXST >

Of course "Camel Case" is a question of your own preferences, but it is
worth to think about it.

Important to know, the EXPORT statements of the exported procedures have
to use the procedure name of the EXTPROC keyword:

strpgmexp pgmlvl(*current) signature('Date utilities')
export symbol('DATEUTIL_PopupCalendar_show')
endpgmexp


Just my two cents.

Thomas.


rpg400-l-bounces@xxxxxxxxxxxx schrieb am 06.01.2014 23:38:07:

Von: kc2hiz@xxxxxxxxx
An: rpg400-l@xxxxxxxxxxxx,
Datum: 06.01.2014 23:38
Betreff: Re: Need some ammunition (Procedures vs. Sub-routines)
Gesendet von: rpg400-l-bounces@xxxxxxxxxxxx

On 1/6/2014 2:49 PM, Booth Martin wrote:
I wish I understood service programs better. There is one application
I
believe would be an excellent service program but I do not know how to
do it.

http://martinvt.com/Code_Samples/Pop-up_Calendar/pop-up_calendar.html

It is a pop-up calendar. Its not my code but I have shown it on my
web
site and I have modified it and C. Wilt fixed it up a couple of years
ago. It just seems to me that it would be a desirable service
program.

My response is hopefully broad enough to be on topic. Specifically, I
will write about how to organise the various pieces and parts so that
there is a minimum amount of work needed to find and modify them in the
future.

ILE is complicated. On purpose. The idea is to be incredibly flexible
so that an application designer has many options available. That sounds
like bad news, but the good news is that with a tiny bit of work, most
of the complexity of ILE goes away. We need to talk about ILE because
we need to be out of the default activation group when using
sub-procedures. So here goes.

Using Booth's calendar as the example, I'd create a member in QRPGLESRC
called DATEUTIL. In that source member, I will have the source for
every date utility I will ever write, including this function which I'll
call POPCAL. Copy all of the source from UTLCALR into
QRPGLESRC(POPCAL). We'll come back to it.

Create another source member in QPROTOSRC. This is where your
prototypes will go. The new member will be called DATEUTIL - the same
name as the RPG source member you're working on. Copy the PR specs from
UTLCALR and rename the procedure POPCAL. Remove the EXTPGM() parameter.
Save it.

Go back to the QRPGLESRC member. Extract out the H specs for dftactgrp
and actgrp and add one for nomain. Add d/copy qprotosrc,dateutil
Change the name on the pi to POPCAL. Add a P POPCAL B...E pair. Put
EXPORT on the P POPCAL B. CRTRPGMOD on it (SEU option 15). There
should be two errors at this point:
1) The display file never gets closed.
2) *INZSR is not allowed.

Closing the display file is easy. Make the file USROPN. Before the
screen size check, add open popcalfm; Before the return (just before
the subroutines) add close popcalfm; (Yeah, I renamed that too.)

*INZSR is a little trickier, but not by much. What is that code doing?
Setting up a default parameter. That can be moved immediately above,
under the PI (just before the open popcalfm.)

Let's take a moment to sum up what's been done, structurally.
1) Created QRPGLESRC(DATEUTIL). This will contain every subprocedure
relating to date manipulation. For now, there's only one - POPCAL.
2) Created QPROTOSRC(DATEUTIL). This will contain prototypes and
'standard' date constants that every caller of the date utilities will
want. Right now, there's only the prototype for POPCAL.
3) Created a *MODULE called DATEUTIL.

Before we create the service program, let's do the tiny bit of work that
will make it easy to consume these date utility procedures. Create a
source file, QSRVSRC. Add a member called DATEUTIL. (Yes, all the
source members have the same name because it makes it easier to work on
next year when you've forgot where all the pieces are.) Make an export
block:

strpgmexp pgmlvl(*current) signature('Date utilities')
export symbol(popcal)
endpgmexp

Yes, I now advise using a programmer-named signature. You'll be adding
new exports to the end of the block anyway, so why bother with *PRV?

Create the service program: CRTSRVPGM SRVPGM(DATEUTIL) EXPORT(*SRCFILE)

Create a binding directory (CRTBNDDIR DATEUTIL).
ADDBNDDIRE BNDDIR(DATEUTIL) OBJ((DATEUTIL)) to put your service program
in it.

You now have all the constituent parts in a service program, ready for
someone to use. Let's do.

h dftactgrp(*no) actgrp('MYCOMPANY')
h bnddir('DATEUTIL')
d/copy qprotosrc,dateutil
d date s d inz(*loval)
popcal(date);
dsply date;
*inlr = *on;

Compile with CRTRPGMOD (SEU option 14) and call it. Up pops your
display file and when you pick a date, it gets displayed in the job log.

If you want to tinker the service program, CRTRPGMOD, then either
CRTSRVPGM again or UPDSRVPGM. Remember to export(*SRCFILE).

Lessons learnt:
1) Use one source member per service program.
2) Put multiple, related sub-procedures in that source member.
3) Name all the source members the same. In the future, when you go
looking (didn't I write a date utility that does...) you'll go to
QPROTOSRC, eyeball the list of members (there won't be that many), find
DATEUTIL and search there. Everything you need to know about the
procedure is right there in QPROTOSRC: the name, the binding directory,
the /copy - everything.
a) QRPGLESRC
b) QPROTOSRC
c) QSRVSRC
4) Use a binding directory so your colleagues can make changes and
recompile without needing a ouija board to work out how the pieces /
parts were assembled.
5) It doesn't take that long to do all this stuff. I assembled a
working service program while typing this up in under an hour.

--buck
--
This is the RPG programming on the IBM i (AS/400 and iSeries)
(RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/rpg400-l.



--
IMPORTANT NOTICE:
This email is confidential, may be legally privileged, and is for the
intended recipient only. Access, disclosure, copying, distribution, or
reliance on any of it by anyone else is prohibited and may be a criminal
offence. Please delete if obtained in error and email confirmation to the sender.

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.