× 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.



Tim,

This is long, but hopefully I can clarify a few things for you...

On Wed, 2003-10-15 at 00:10, Tim Kredlo wrote:
> Define a prototype for the subprocedure (TESTSP). and store it in the
> source PROTSP.
>
> It will return a numeric field 15 characters long with 3 decimals
>  and it requires 3 numeric input parameters.
>       D TestSP        PR            15S 3
>       D Unit                             2S 0
>       D Qnty                            8S 0
>       D Long                            3S 0
> 
> So far, so good.

Storing your prototype in a /copy book is not a requirement but I
definitely recommend it, which I'll explain later.

> Now I am going to write the subprocedure itself. 
>       H NOMAIN
>       // Include the prototype
>        /Copy PRODLIB/QRPGSRC/PROTSP

Not to be picky, but this should be:
 /copy prodlib/qrpgsrc,protsp
Note the comma in between the file and member names.  Also, since this
isn't a literal ALLCAPS are not required.

> Still OK. BUT then:
>       // Define the procedure interface
>       D TestSP      PI
>       D Unit                             1A
>       D Qnty                            8S 0
>       D Long                            3S 0

Good questions:
> Why is this necessary?
This is necessary because this defines the *ENTRY for that procedure. 
The prototype is nothing more than a set off "calling rules" for any
other piece of code that wants to use this procedure.  The PI is
actually used to execute the call.

> Didn't the included prototype already declare these fields?
No.  The prototype does NOT declare fields in any way.  In fact, the
field names are in a prototype have no value beyond documentation.

This means that:
        D TestSP        PR            15S 3
        D Unit                             2S 0
        D Qnty                            8S 0
        D Long                            3S 0
has the exact same affect as:
        D TestSP        PR            15S 3
        D                                                               2S 0
        D                                                               8S 0
        D                                                               3S 0

> Wasn't that the purpose of the prototype?
No.  The purpose of a prototype is to ensure that the caller is obeying
the rules established by the interface: i.e. the prototype enforces the
procedure call.  The nice thing is that this enforcement is checked at
compile time whereas with RPGIII and OPM parm mismatch errors would only
show up at runtime.

Before I proceed it is important to point out that this PI does not
match the PR you are using and as such would never compile.  The PI is
missing the return value, and the first parm in the PR is defined as "2S
0" while the first parm in the PI is defined as "1A".

The thing about PRs and PIs is that they must be functionally
equivelant.  In fact, other than the field names they must match.  This
is why we put them in /copy books, to ensure that both the module itself
and any calling module are using the same PR.  Since they have to be the
same, I typically copy the actual PI from my code into my /copy book and
simply change "PI" to "PR".

>       // Declare the field to be returned:
>       D Footage                     15S 3
Hmmm.  There is something a"foot" here (sorry) - once you've added the
return value to your PI you have defined the definition of what is to be
returned.  Now in your procedure you must have an actual field to
return, and that field must be defined the same as your PI indicates.  
In this example, Footage should be a standalone field, with the S like
so:
        // Declare the field to be returned:
>       D Footage         S            15S 3

> Why is this necessary?
This is just the work field for your procedure.  When your procedure is
done you will issue the return statement using this field:
    return Footage ;

You notice that neither the PI nor the PR give you a facility to "name"
the return field, just the definition, so you can call this field
whatever you want as long as it is defined the same as the retunr value
on your PR and PI.

> Didn't the prototype already declare the return value
> type/length/decimals?

The prototype did but the PI did not (and should have as discussed
above), and again, the PR doesn't actually declare/define it the PI
does.
        
>       /Free
>       //Calculate the return value
>       Footage = Unit * Qnty * Long; 
>       // Return the calculated value
>       Return Footage;
>       /End-Free
> 
> I must be missing some very basic concepts, because I would have thought
> that the following was ALL that SHOULD be necessary for subprocedure
> TestSP:
> 
>       H NOMAIN
>       // Include the prototype
>       /Copy PRODLIB/QRPGSRC/PROTSP
>       // Calculate and return value
>       /Free
>        TestSP = Unit * Qnty * Long;
>       /End-Free
> 
> No PI defined - already did that in the prototype.
> No "Return" variable defined - use the subprocedure name. Type, etc.
> defined on prototype PR line.
> No Return statement required - stated in prototype that the subprocedure
> returns a 15S 3 variable.

I think if you'll go back through the changes we made above these should
be corrected.

> Please - what am I missing?
> Where can I go to get an explanation as to WHY I need to add
> what I consider (obviously incorrectly) unnecessary coding?

OK, this is the crux of the whole thing:  the PI block is what the
procedure will use at run time, like an old *ENTRY list but much more
powerful.  The field names you define in a PI are variables just like a
PLIST.

The *matching* prototype is used by the calling procedures to validate
their calling statements.  In fact, this is the very point of PRs, so
being able to do this without the PR AND the PI would defeat the purpose
of this approach.

> OR: Am I coding things here that ARE unnecessary?
> 
> Thanks in advance for any help.
> 
> Frustrated, uninformed, and confused (but only in my mind),
> 
> Tim Kredlo

Don't worry, we've all been there.

HTH,

Joel
http://www.rpgnext.com


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.