Thanks for replying, I've been looking at this for a while now but I can't think of a neater way in RPG.
Your solution won't work for a program calling a service program. The enumerate array will only be populated in the service program so the calling program would have to guess integer values to pass. You could redefine the array with default values using inz but the programmer of the calling program would still have the problem of having to know the character literals to do a %Lookup on.
For example:
PHP Code:
enumerate(1) = 'Clubs';
myproc(%lookup('clubs':enumerate));
This code would compile but the %Lookup would return zero which could lead to some interesting problems. The programmer might even try to do a %Lookup on a value that doesn't exist at all in the enumerated type.
I have seen the following technique used in Java, which could port to RPG, but it is generally considered bad practice.
PHP Code:
public class PlayingCard {
public static final int SUIT_CLUBS = 0;
public static final int SUIT_DIAMONDS = 1;
public static final int SUIT_HEARTS = 2;
public static final int SUIT_SPADES = 3;
...
}
It is then possible to pass parameters like PlayingCard.SUIT_CLUBS which would actually pass a zero. The problem with this solution is that it is still possible for the programmer to pass the int directly which is hard to read or an expression like this (PlayingCard.SUIT_CLUBS+PlayingCard.SUIT_HEARTS) or worse still an int that is out of range like (4). All of these would compile ok but would lead to runtime errors.
The solution in Java is to either use an enum type which was introduced in version 5.0 of the jdk or use a splash of OO to make it type safe.
E.G.
PHP Code:
public class Suit
{
private final String name;
private Suit(String name) { this.name = name; }
public String toString() { return name; }
public static final Suit CLUBS =
new Suit("clubs");
public static final Suit DIAMONDS =
new Suit("diamonds");
public static final Suit HEARTS =
new Suit("hearts");
public static final Suit SPADES =
new Suit("spades");
}
You can then define a method to accept only a Suit object.
PHP Code:
public void setSuit(Suit suitIn){...}
This solution is much more robust because the compiler will catch any invalid suits passed to setSuit. The constructor for the Suit type is private so the programmer can't go creating new suits at runtime. As a bonus the code will be much more readable because you have to pass one of the public suit instances. e.g. setSuit(Suit.SPAPDES).
I was hoping that I might find an equally pleasing solution in RPG. I'm thinking now that I'll just have to use the int pattern and hope that it isn't abused. It's better than letting them pass a string literal which could be anything.
I noticed the following line in that wikipedia article.
Some early programming languages did not originally have enumerated types.
This is the trouble when working with early programming languages.
It makes me chuckle when I hear RPG programmers stating that RPG is as good as OO now because it has procedures and service programs. What they're really stating is that they don't understand the benefits of OO! Sorry, rant over. It's not directed at you.
Bookmarks