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



My comments inline.

Joe Pluta wrote:
>
> This is an interesting point, Barbara.  Let's say I want to create a group
> of procedures that are, for lack of a better term, object-like.  By that, I
> mean that I use them to grab data from the database, pass it around to other
> procedures, and eventually perhaps update it.  For example, let's say it's
> item data.
>
> Okay, I want to use a data structure to hold this data.  And since I can
> have multiple "instances" of the data, I want the application, not the
> procedure, to keep track of the storage.  Finally, say that one of the
> procedures is the "create" (or perhaps "get" is a better word) procedure.
> Something like this:
>
> H nomain
> FITEMFILE if      e       disk
> D ItemDS      e ds               extname(ITEMFILE)
>
> D GetItem   pr                   like(ItemDS) EXTPROC('GETITEM')
> D   ItemKey                      like(ITEMNUMBER) const
>
> ITEMBUMBER is an alpha field, so I could conceivably do:
>
> C           eval  ItemDS = GetItem('MyItemKey')
>
> But you're suggesting that returning a DS is not a good idea.  Why is that?

Using a parameter passed by reference, the called procedure just sets
whatever data it wants; no other data is moved around.  Using a return
value, the whole data structure gets copied to wherever the system puts
returned values, and then it has to get copied again to the receiver
(left-hand-side of the EVAL).

> And what would you recommend instead?
>
> D GetItem   pr             10I 0 EXTPROC('GETITEM')
> D   ItemPtr                  *   const
> D   ItemKey                      like(ITEMNUMBER) const
>
> C           eval  rc = GetItem(%addr(ItemDS):'MyItemKey)
>
> And having the called procedure copy the data into the pointer?  I actually
> can see where this might have more utility, because the 'rc' allows for
> better error checking.  I'm just trying to get my head around a generic way
> to handle these sorts of object-based issues.


Since RPG doesn't have typed pointers, whenever you want your called
procedure to get a specific type, it's best to pass it by reference.
Otherwise, the caller can pass the address of anything.

So I wouldn't use a pointer, I would just pass the DS by reference.  The
caller can declare as many DS's as he wants.  If you are at V5R1, you
could use LIKEDS to declare multiple similar DS's.  But before V5R1, if
the caller wanted multiple versions of the same DS, he'd have to have
multiple versions of the storage, and then set a basing pointer of the
DS with the subfields to the correct bit of storage.  Either way, the
caller can manage the storage by just passing a name.


>
> Way back when, we did exactly this sort of thing with C, although we usually
> went one step further:
>
> H nomain
> FITEMFILE if      e       disk
> D ItemDS      e ds               extname(ITEMFILE) BASED(pItemDS)
>
> D GetItem   pr                   like(pItemDS) EXTPROC('GETITEM')
> D   ItemKey                      like(ITEMNUMBER) const
>
> C           eval  pItemDS = GetItem('MyItemKey)
>
> GetItem would actually allocate the memory for the ItemDS and return it.
> We'd check pItemDS for null to check for an error.  I suppose I could just
> as easily code:
>
> D GetItem   pr             10I 0 EXTPROC('GETITEM')
> D   ItemPtr                      like(pItemDS)
> D   ItemKey                      like(ITEMNUMBER) const
>
> C           eval  rc = GetItem(pItemDS:'MyItemKey)
>
> Since pItemDS is not constant, the called procedure could allocate the
> memory and update the pointer.

For GetItem procedures, most items are probably small enough to be
returned by value.  But rather than a single GetItem with a key, I'd
have a GetFld1, GetFld2 etc, and just return the thing.  I would never
give my caller a pointer into my data structure.  Add Set procedures to
set new values instead.

And instead of giving the caller a pointer to the DS itself in the first
place, I'd just give an index into an array (or an occurrence).




As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
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.