%PASSED
Paramètre facultatif transmis ?
Indique si un paramètre facultatif (options(*nopass)) a bien été transmis avec une valeur par l'appelant.
Syntaxe
%PASSED(paramètre)
paramètre- Le nom d'un paramètre de la procédure en cours, déclaré avec
options(*nopass). - Résultat
- Un indicateur :
*ONsi le paramètre a été transmis avec une valeur,*OFFs'il n'a pas été transmis ou s'il a été passé avec*OMIT.
À quoi ça sert
Les paramètres facultatifs permettent de faire évoluer une procédure sans casser les appels existants : on ajoute un paramètre en fin de liste avec *nopass, et les anciens appels continuent de fonctionner.
À l'intérieur, %PASSED se lit comme une phrase : if %passed(ville);. C'est plus clair que comparer %PARMS à un chiffre.
Exemple 1 : Un libellé avec ou sans ville
**free
// %PASSED : un parametre facultatif a-t-il ete transmis ?
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr libelle varchar(60);
nom varchar(30) const;
ville varchar(30) const options(*nopass);
end-pr;
snd-msg libelle('Dupont SA');
snd-msg libelle('Dupont SA' : 'Montpellier');
*inlr = *on;
dcl-proc libelle;
dcl-pi *n varchar(60);
nom varchar(30) const;
ville varchar(30) const options(*nopass);
end-pi;
if %passed(ville);
return nom + ' (' + ville + ')';
endif;
return nom + ' (ville inconnue)';
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Dupont SA (ville inconnue)
Dupont SA (Montpellier)
Le premier appel ne passe que le nom : %passed(ville) est faux, on renvoie « ville inconnue ». Le second passe la ville, on l'ajoute au libellé.
Exemple 2 : Lire sans tester
**free
// %PASSED : lire un parametre non transmis sans le tester plante.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr libelle varchar(60);
nom varchar(30) const;
ville varchar(30) const options(*nopass);
end-pr;
snd-msg libelle('Dupont SA');
*inlr = *on;
dcl-proc libelle;
dcl-pi *n varchar(60);
nom varchar(30) const;
ville varchar(30) const options(*nopass);
end-pi;
return nom + ' (' + ville + ')';
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Erreur : MCH3601 - Pointeur non défini pour position mémoire référencée.
Ici l'appel ne transmet pas la ville et la procédure la lit quand même. Le programme s'arrête sur une erreur MCH3601 (pointeur non défini) : il n'y a rien derrière le paramètre absent.
Exemple 3 : Non transmis, omis, transmis : les trois cas
**free
// %PASSED, %OMITTED et %PARMS : les trois cas d'un parametre facultatif.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr essai;
ville char(10) const options(*nopass : *omit);
end-pr;
essai('Lyon');
essai(*omit);
essai();
*inlr = *on;
dcl-proc essai;
dcl-pi *n;
ville char(10) const options(*nopass : *omit);
end-pi;
dcl-s t varchar(60);
t = 'parms=' + %char(%parms());
if %passed(ville);
t += ' passed';
else;
t += ' pas-passed';
endif;
if %omitted(ville);
t += ' omitted';
else;
t += ' pas-omitted';
endif;
snd-msg t;
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
parms=1 passed pas-omitted
parms=1 pas-passed omitted
parms=0 pas-passed pas-omitted
Même procédure, trois appels. Avec 'Lyon' : %PASSED vrai, %OMITTED faux. Avec *omit : les deux sont inversés, et %PARMS vaut toujours 1. Sans paramètre : %PARMS vaut 0, et les deux tests sont faux.
Le piège
Un paramètre passé avec *OMIT n'est pas « passé ». Dans l'exemple 3, essai(*omit) donne %PASSED faux, alors que %PARMS compte bien 1 paramètre. Pour lire la valeur en sécurité, il suffit de tester %PASSED : il couvre à la fois le cas non transmis et le cas omis.
Lire un paramètre *nopass sans avoir testé %PASSED plante avec MCH3601 (exemple 2).