|
> -----Original Message----- > From: rpg400-l-bounces@xxxxxxxxxxxx > [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Scott Klement > Sent: Friday, April 21, 2006 6:21 PM > To: RPG programming on the AS400 / iSeries > Subject: Re: *NOPASS and *OMIT make calling easier but boy > are the proceduresugly, any tips/tricks? > > > > However, as far as I can tell actual implementation is ugly beyond > > belief. > > One trick comes to mind... an *OMIT parameter is the same > thing as a > parameter who's address is *NULL. (In fact, the way you check for an > *OMIT parameter is by checking if %addr() = *NULL) > > Consequently, you could do this: > > D wToBin s 10A based(p_wToBin) > D memToBin s like(wToBin) > > /free > if bin_Required(); > p_wToBin = %addr(memToBin); > wToBin = AskUserForBin(); > else; > p_wToBin = *NULL; > endif; > > > Inventory_MoveSerialized(wPlant:wSerial:wToStkRm:wToBin); > > /end-free > > When the bin isn't required, the address of wToBin is set to > *NULL. That > means it'll look like *OMIT to the procedure you call. This > saves you > from having to code the subprocedure call in two places. Scott, Yes I realized this, however I'm still trying to decide if it is worth the effort or not. In the example above, for instance I don't think it is. But in the more complicated examples discussed below it might be. > > > /free > > if %parms >= 5; > > if parm5 <> *OMIT; > > SomeOtherProc1(plant:parm5); > > else; > > SomeOtherProc1(plant:*OMIT); > > endif; > > else > > SomeOtherProc1(plant); > > endif; > > For stuff like this, I usually figure out my parameters at > the beginning. > For example: > > if %parms >= 4 and %addr(Parm4)<> *NULL; > local4 = Parm4; > else; > local4 = 'Default Value'; > endif; > > if %parms >= 5 and %addr(Parm5) <> *NULL; > Local5 = Parm5; > else; > Local5 = 'Default Value'; > endif; The problem I have is that I want my default value to be *OMIT. Here at least I may use the local copy with a basing pointer discussed above. In particular the basing pointer technique should simplify the code where SomeOtherProc3 is called. Using the basing pointer technique was the only thing I could come up with to simplify the code, I was hoping there was some other method I was missing. But it'd be much easier if RPG allowed 1) A default value for a non-passed parameter like C++ 2) a variable to be set to NULL/*OMIT. I think I'd open a DCR, thus making Rob proud. <grin> > > This example is specifically for input-only parameters (i.e. > CONST parms!) > Because there's a local variable that's set, the procedure > can simply use > the local variable, and it doesn't have to have two sets of > code for each > thing that it does. > > Naturally, it won't work for bi-directional or output > parameters, since > the Local5 variable isn't ever passed back. So for bi-directional or > output parameters, you can do it this way: > > D Local5 s like(Parm5) > D based(p_Local5) > D memLocal5 s like(Parm5) > > > if %parms >= 5 and %addr(Parm5) <> *NULL; > p_Local5 = %addr(Parm5); > else; > p_Local5 = %addr(memLocal5); > endif; Sweet idea, but luckily I'm only dealing with input params at this time. > > If the parm is passed, changes made to Local5 would change the > parameter and be returned to the caller. If not, it'll > change some local > storage, which doesn't hurt anything. > > If you need to be able to pass it on to the next procedure, > you can pass > Local5 to that procedure, and the next procedure will get your local > storage or the caller's storage, again, depending on whether > the parm was > passed. > > If the procedure that you call needs to know whether the > original caller > actually passed it or not, you can have a second based > variable that's a > "to be passed on" copy. For example > > D Local5 s like(Parm5) > D based(p_Local5) > D PassMe5 s like(Parm5) > D based(p_PassMe5) > D memLocal5 s like(Parm5) > > > if %parms >= 5 and %addr(Parm5) <> *NULL; > p_Local5 = %addr(Parm5); > p_Passme5 = %addr(Parm5); > else; > p_Local5 = %addr(memLocal5); > p_Passme5 = *NULL; > endif; > > Now when you need to pass it on, you pass "Passme5" and it'll > automatically be set to *OMIT if the parameter wasn't passed. > If it was > passed, it'll be viewing the same memory that Local5 and the > caller's parm > were viewing, so the caller will know whether a parameter was > passed or > not, and can act differently if it needs to. > > It's still somewhat ugly, but I think it's somewhat easier to > maintain > than the method you posted. If nothing else, it's food for thought. Again, sweet idea, but as it stands now I shouldn't need to use it. I'll keep it in mind for the future though. As always Scott, thank you for the well written and informative reply. "Food for thought"??? More like a 3 course dinner. <grin> Thanks again, Charles Wilt -- iSeries Systems Administrator / Developer Mitsubishi Electric Automotive America ph: 513-573-4343 fax: 513-398-1121
As an Amazon Associate we earn from qualifying purchases.
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.