Instruction RPG full free · IBM i (AS/400) · Déclarations
DCL-PI
Déclarer l'interface d'une procédure
Décrit, à l'intérieur d'une procédure, ses paramètres et le type de la valeur qu'elle retourne ; elle doit correspondre au prototype.
Syntaxe
dcl-pi nom | *n [type de retour];
paramètre type(longueur) [const | value] [options(*nopass : *omit)];
end-pi;
dcl-pi *n packed(9:2); montant packed(9:2) const; end-pi;
nom | *n- Le nom de la procédure, ou
*npour reprendre celui dedcl-proc(la forme habituelle). type de retour- Le type de la valeur renvoyée par
return. Absent si la procédure ne renvoie rien. paramètres- Les paramètres reçus, avec les mêmes mots-clés que dans le prototype :
const,value,options(*nopass : *omit). - Effet
- Aucun indicateur ni %FOUND. La déclaration crée les paramètres comme des variables de la procédure.
%parmsdonne le nombre de paramètres réellement passés par l'appelant.
À quoi ça sert
dcl-pi est le pendant, dans la procédure, du dcl-pr de l'appelant. Le prototype dit comment on appelle ; l'interface dit ce qu'on reçoit. Les deux décrivent les mêmes paramètres, avec les mêmes types et les mêmes mots-clés.
Pour un paramètre facultatif, options(*nopass) permet à l'appelant de ne pas le passer, ce qui évite d'écrire plusieurs procédures presque identiques. %parms permet alors de savoir ce qui a été fourni. En RPG IV en colonnes, c'était la spécification D avec le code PI.
Exemple 1 : Paramètres facultatifs et %PARMS
**free
// DCL-PI : l'interface de la procedure; OPTIONS(*NOPASS) rend un parametre facultatif.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr libelle varchar(60);
nom char(20) const;
ville char(15) const options(*nopass);
solde packed(9:2) const options(*nopass);
end-pr;
snd-msg libelle('Dupont SA');
snd-msg libelle('Dupont SA' : 'Montpellier');
snd-msg libelle('Dupont SA' : 'Montpellier' : 1250.50);
*inlr = *on;
dcl-proc libelle;
dcl-pi *n varchar(60);
nom char(20) const;
ville char(15) const options(*nopass);
solde packed(9:2) const options(*nopass);
end-pi;
dcl-s texte varchar(60);
texte = %trim(nom);
if %parms >= 2;
texte += ' a ' + %trim(ville);
endif;
if %parms >= 3;
texte += ', solde ' + %char(solde);
endif;
texte += ' (' + %char(%parms) + ' parametre(s))';
return texte;
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Dupont SA (1 parametre(s))
Dupont SA a Montpellier (2 parametre(s))
Dupont SA a Montpellier, solde 1250.50 (3 parametre(s))
Avec un, deux ou trois arguments, le même texte s'allonge selon ce qui est fourni. %parms dit combien de paramètres ont été passés : on ne lit ville que s'il y en a au moins deux, et solde qu'à partir de trois.
Exemple 2 : Lire un paramètre non passé
**free
// DCL-PI : un parametre facultatif non transmis ne doit pas etre lu sans verification.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr remise packed(9:2);
montant packed(9:2) const;
taux packed(5:2) const options(*nopass);
end-pr;
snd-msg 'Avec taux : ' + %char(remise(1000 : 10));
snd-msg 'Sans taux : ' + %char(remise(1000));
*inlr = *on;
dcl-proc remise;
dcl-pi *n packed(9:2);
montant packed(9:2) const;
taux packed(5:2) const options(*nopass);
end-pi;
return montant * taux / 100;
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Avec taux : 100.00
Sans taux : 100.00
La procédure remise lit taux sans vérifier s'il a été passé. L'appel avec le taux donne bien 100,00 ; l'appel sans taux ne donne pas d'erreur non plus, mais une valeur au hasard : ici 100,00, comme si le taux valait 10. Le résultat est faux.
Exemple 3 : Tester %PARMS et utiliser *OMIT
**free
// DCL-PI : la meme procedure, protegee par %PARMS, et OPTIONS(*OMIT) pour sauter un parametre.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr remise packed(9:2);
montant packed(9:2) const;
taux packed(5:2) const options(*nopass : *omit);
end-pr;
snd-msg 'Avec taux : ' + %char(remise(1000 : 10));
snd-msg 'Sans taux : ' + %char(remise(1000));
snd-msg 'Omis : ' + %char(remise(1000 : *omit));
*inlr = *on;
dcl-proc remise;
dcl-pi *n packed(9:2);
montant packed(9:2) const;
taux packed(5:2) const options(*nopass : *omit);
end-pi;
dcl-s tauxEff packed(5:2) inz(5);
if %parms >= 2 and %addr(taux) <> *null;
tauxEff = taux;
endif;
return montant * tauxEff / 100;
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Avec taux : 100.00
Sans taux : 50.00
Omis : 50.00
La même procédure, protégée : si le taux manque (ou est omis avec *omit), on utilise 5 %. %addr(taux) <> *null détecte un paramètre omis. Les trois appels donnent 100, 50 et 50.
Le piège
Un paramètre *nopass non passé n'est pas une erreur, c'est une valeur au hasard. Dans l'exemple 2, remise(1000) lit un taux qui n'existe pas et renvoie 100,00 : la valeur est celle qui traîne en mémoire, aucun message d'erreur. Testez toujours %parms (exemple 3) avant de lire un paramètre facultatif. Pour un paramètre sauté avec *omit, testez %addr(paramètre) <> *null.