Guru: RPG Select Operation Gets Some Sweet Upgrades
September 23, 2024 Gregory Simmons
I have always been a fan of RPG’s Select operation. Any time I’m coding an If statement and think there’s a chance that there could be a third situation other than the If-Else conditions, I will go ahead and code the Select operation instead of the If statement. The RPG language’s Select operation got a pretty sweet upgrade in V7R5 TR2 and V7R4 TR8. Now, the Select statement can be presented with a value and we have two new op-codes to use within the Select operation; When-is and When-in.
DISCLAIMER: The edibility of the mushrooms listed in my test program are purely to give the program a little context and make it interesting. Their edible status is from the publication by the Missouri Department of Conservation’s A Guide to Missouri’s Edible and Poisonous Mushrooms. Before foraging for and/or consuming any wild mushroom do your research and be safe.
First let’s explore how the change to the Select line can reduce repetition (and in my opinion makes it easier to read) in our code. Prior to this enhancement, if I needed to test the upper case of a variable for one value or in an array, I would write a Select statement like this:
Dcl-Proc known_safe_mushrooms; Dcl-Pi known_safe_mushrooms Ind; p_new_mushroom Char(20); End-Pi; Dcl-S safe_mushrooms Like(p_new_mushroom) Dim(3); safe_mushrooms = %List('SHIITAKE':'PORTOBELLO':'MOREL'); Select; When %Upper(p_new_mushroom) = 'CHANTERELLE'; Return *On; When %LookUp(%Upper(p_new_mushroom):safe_mushrooms) > 0; Return *On; Other; Return *Off; EndSl; Return *Off; On-Exit; End-Proc known_safe_mushrooms;
I could have combined the two When statements with an ‘Or’, but for demo purposes, I kept them separate. The point is that each condition I want to test needs to repeat the %Upper BIF usage. Now, let’s look at the same Select statement from above with the improvements:
Dcl-Proc known_safe_mushrooms; Dcl-Pi known_safe_mushrooms Ind; p_new_mushroom Char(20); End-Pi; Dcl-S safe_mushrooms Like(p_new_mushroom) Dim(3); safe_mushrooms = %List('SHIITAKE':'PORTOBELLO':'MOREL'); Select %Upper(p_new_mushroom); When-in safe_mushrooms; Return *On; When-is 'CHANTERELLE'; Return *On; Other; Return *Off; EndSl; Return *Off; On-Exit; End-Proc known_safe_mushrooms;
In the above example, note that I just code the %Upper BIF once, on the Select line. Then all conditions following will be testing on the upper-case value of the parameter which was passed in.
Next, notice that to test if the value is in the array safe_mushrooms, I was able to remove the need to nest two BIFs and use the When-in statement instead. What do you think? Sure, we’re all comfortable with nesting BIFs to get our desired outcome, but I think this improves the readability of my code; especially if a new RPG programmer needs to read it.
And my second When statement has also become more succinct in that the need for another %Upper BIF is eliminated. I like how When-in and When-is make my RPG seem more self-documenting.
The When-is clause is especially useful because it evaluates a condition as either true or false. While the previous example tested for an exact value, you can now use any expression that yields a true or false result. Let’s explore that:
Dcl-Proc Demo_Select; Dcl-s new_mushroom Char(20); Dcl-s probably_safe Ind; Select %Upper(new_mushroom); When-is 'MOREL'; probably_safe = *On; When-is known_safe_mushrooms(new_mushroom); probably_safe = *On; When-in %Range('BOLETE':'CHANTERELLE'); probably_safe = *On; When-in %List('SHIITAKE':'PORTOBELLO'); probably_safe = *On; Other; probably_safe = *Off; EndSl; End-Proc Demo_Select;
In this example, I show how you can make use of the %Upper BIF once for the whole Select operation. The When-is statement is used for testing of one value as well as calling the procedure in the previous example. Then two variations of the When-in statement; one making use of the %Range BIF and one using the %List BIF.
Okay, that’s cool. But wait, there’s more! Notice that, in the above examples, I showed the usage of a BIF on the Select statement. We can also evaluate any combination of expressions on this statement. For example, what if we had another procedure that would ask the user for an uncategorized mushroom, ask_user_for_mushroom(), and then evaluate the Select operation on whatever the user keyed in (on a green screen app or web app, etc.):
Dcl-Proc Demo_Select; Dcl-s new_mushroom Char(20); Dcl-s probably_safe Ind; Select %Upper(ask_user_for_mushroom()); When-is 'MOREL'; probably_safe = *On; When-is known_safe_mushrooms(new_mushroom); probably_safe = *On; When-in %Range('BOLETE':'CHANTERELLE'); probably_safe = *On; When-in %List('SHIITAKE':'PORTOBELLO'); probably_safe = *On; Other; probably_safe = *Off; EndSl; End-Proc Demo_Select;
In this Select statement, I can ask the user for a mushroom they want to test, then uppercase whatever they provided and perform the tests. Frequent readers of my articles know I am a big fan of Procedure Driven RPG, and this is a great example of encapsulating whatever business logic I need to in the procedure to get me a mushroom to test. That business logic is not important here. Pretty fantastic!
The %Subarr BIF can also be used with the When-in statement. I will let you forage that one on your own.
I feel like this is an enhancement I’m going to be using a lot!
Until next time, happy coding.
Gregory Simmons is a software engineer with P.C. Richard & Son. He started on the IBM i platform in 1994, graduated with a degree in Computer Information Systems in 1997 and has been working on the OS/400 and IBM i platform ever since. He has been a registered instructor with the IBM Academic Initiative since 2007, and holds a COMMON Application Developer certification. When he’s not trying to figure out how to speed up legacy programs, he enjoys speaking at technical conferences, running, backpacking, hunting, and fishing.
RELATED STORIES
Guru: Growing A More Productive Team With Procedure Driven RPG
Guru: With Procedure Driven RPG, Be Precise With Options(*Exact)
Guru: Testing URLs With HTTP_GET_VERBOSE
Guru: Fooling Around With SQL And RPG
Guru: Procedure Driven RPG And Adopting The Pillars Of Object-Oriented Programming
Guru: Getting Started With The Code 4 i Extension Within VS Code
Guru: Procedure Driven RPG Means Keeping Your Variables Local
Guru: Procedure Driven RPG With Linear-Main Programs
Guru: Speeding Up RPG By Reducing I/O Operations, Part 2
Guru: Speeding Up RPG By Reducing I/O Operations, Part 1
Guru: Watch Out For This Pitfall When Working With Integer Columns