ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Enumerated type

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Enumerated type

    I'm writing a new service program and I could do with creating an enumerated type. Can anyone think of a way to do this in ILE RPG?

    I suppose I could define the types as constants in the /copy member where my prototypes are. Then the procedure where I want them to pass the enum could receive an integer. It might look a bit like this (I know the positions are wrong):
    PHP Code:
    DConst1      Const(1)
    DConst2      Const(2
    PHP Code:
    MyProc(Const1); 
    This is sort of how we used to do it in Java until they added proper enumerated types to the Java language.

    Can anyone think of a neater solution?
    A description of enumerated types can be found here:
    Ben

  • #2
    Re: Enumerated type

    for simple integers you could use arrays with %lookup
    Code:
         hoption(*nodebugio:*srcstmt) dftactgrp(*no)
         denumerate        s             10a   Dim(4)
         dmyproc           pr
         d int_value                      5i 0 Const
    
          /free
            enumerate(1) = 'Clubs';
            enumerate(2) = 'Diamonds';
            enumerate(3) = 'Spades';
            enumerate(4) = 'Hearts';
    
            myproc(%lookup('Clubs':enumerate));
            myproc(%lookup('Diamonds':enumerate));
            myproc(%lookup('Spades':enumerate));
            myproc(%lookup('Hearts':enumerate));
            myproc(%lookup('Garbage':enumerate));
    
            *inlr=*on;
            return;
    
          /end-free
         pmyproc           b
         dmyproc           pi
         d int_value                      5i 0 Const
          /free
             dsply %char(int_value) ' ';
             return;
          /end-free
         pmyproc           e
    is that what you're after?
    I'm not anti-social, I just don't like people -Tommy Holden

    Comment


    • #3
      Re: Enumerated type

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

      Comment


      • #4
        Re: Enumerated type

        What about using qualified structure like this:
        Code:
        D colors          ds                  qualified
        D  white                         1  0 inz(1)   
        D  red                            1  0 inz(2)
        You can define it in one member and copy to other using \copy directive as you wrote before.
        This way is more similar to OO enumerated type. You can use this in functions like this:
        Code:
        MyProc(colors.white);

        Comment

        Working...
        X