MainframeSupports
tip uge 49/2014:

For tolv uger siden skrev jeg et tip om rekursion i COBOL. Nu er tiden kommet til PLI. PLI er et såkaldt procedurelt sprog med mulighed for at definere interne procedurer med parameteroverførsel og lokale variable. Derfor ligger muligheden for at lave rekursive kald noget mere lige for end i COBOL. Jeg har skrevet eksemplet fra COBOL tippet så direkte som muligt over til PLI:

parsing: PROC(jclparm) OPTIONS(MAIN);
DCL jclparm CHAR(100) VAR;
DCL needlepos FIXED BIN(31);
DCL parmno FIXED BIN(15) INIT(0);
DCL pgmparm CHAR(100) VAR;
pgmparm = jclparm;
CALL pgmstart;
pgmstart: PROC;
  DCL localno FIXED BIN(15);
  parmno = parmno + 1;
  localno = parmno;
  IF length(pgmparm) > 0
  THEN DO;
    needlepos = index(pgmparm, ',');
    IF needlepos = 0
    THEN
      needlepos = length(pgmparm) + 1;
    PUT SKIP LIST('PARM-NO='!!parmno!!', LOCAL-NO='!!localno
                 !!', VALUE=<'!!substr(pgmparm,1,needlepos - 1)!!'>'
                 );
    IF needlepos <= length(pgmparm)
    THEN DO;
      pgmparm = substr(pgmparm, needlepos + 1);
      CALL pgmstart;
      PUT SKIP LIST('PARM-NO='!!parmno!!', LOCAL-NO='!!localno
                   !!' AFTER RECURSION'
                   );
    END;
  END;
END pgmstart;
END parsing;

I modsætning til COBOL, så har alle procedurekald i PLI hver deres egen retur-adresse, uanset hvor mange gange en procedure kaldes. Derfor kan man i PLI ikke komme galt afsted med rekursive kald som i COBOL. PLI manualen foreskriver, at man benytter option RECURSIVE på procedurer, der kaldes rekursivt, men det er ikke et krav, og det gør normalt ingen forskel. Der findes dog meget specielle situationer omkring parameteroverførsel, hvor brugen af RECURSIVE gør en forskel.

I ovenstående eksempel vil det være langt mere elegant at have pgmparm som parameter i pgmstart proceduren. Det første kald til pgmstart ville så være CALL pgmstart(jclparm) og det rekursive kald ville være CALL pgmstart(substr(pgmparm, needlepos + 1)) og statement pgmparm = substr(pgmparm, needlepos + 1) skal fjernes. Så bliver det procedurelle ved PLI ligesom bedre udnyttet. Læg også mærke til, at lokale variable i PLI er rigtige lokale variable og ikke som i COBOL globale variable for den igangværende eksekvering af hele programmet.

Forrige danske tip        Last tip in english        Tip oversigten