Instruction RPG full free · IBM i (AS/400) · Procédures, sous-programmes et erreurs
ON-EXIT
Nettoyage à la sortie d'une procédure
Déclare, à la fin d'une procédure, un bloc exécuté à chaque sortie, que la procédure se termine normalement, par un RETURN anticipé ou par une erreur.
Syntaxe
ON-EXIT {indicateur};
instructions de nettoyage
END-PROC;
indicateur- Zone indicateur facultative. Elle vaut
*ONsi la procédure se termine à cause d'une erreur,*OFFsinon. - Effet
- L'indicateur, s'il est donné, est positionné avant l'exécution du bloc :
*OFFpour une sortie normale,*ONpour une sortie sur erreur. L'ON-EXIT s'exécute avant que l'appelant ne reprenne la main.
À quoi ça sert
Une procédure qui ouvre un fichier, réserve un verrou ou crée un objet temporaire doit le libérer sur tous ses chemins de sortie : fin normale, plusieurs return anticipés, erreur. Au lieu de dupliquer le nettoyage avant chaque return, on l'écrit une seule fois dans ON-EXIT.
Le bloc se place à la fin de la procédure, juste avant END-PROC. Dans le premier exemple, il s'exécute aussi bien après la sortie normale du client 100 qu'après le return *off anticipé du client 0.
Exemple 1 : Nettoyage après sortie normale et après RETURN anticipé
**free
// ON-EXIT : bloc de nettoyage execute a la sortie d'une procedure, quelle que soit la sortie.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr traiter ind;
numcli packed(5:0) const;
end-pr;
dcl-s ok ind;
snd-msg 'Appel 1 : client 100';
ok = traiter(100);
snd-msg 'Resultat : ' + %char(ok);
snd-msg 'Appel 2 : client 0 (refuse)';
ok = traiter(0);
snd-msg 'Resultat : ' + %char(ok);
*inlr = *on;
dcl-proc traiter;
dcl-pi *n ind;
numcli packed(5:0) const;
end-pi;
dcl-s arret ind;
snd-msg ' Ouverture de la ressource pour ' + %char(numcli);
if numcli = 0;
snd-msg ' Client invalide, sortie anticipee';
return *off;
endif;
snd-msg ' Traitement du client ' + %char(numcli);
return *on;
on-exit arret;
snd-msg ' ON-EXIT : fermeture, sortie anormale = ' + %char(arret);
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Appel 1 : client 100
Ouverture de la ressource pour 100
Traitement du client 100
ON-EXIT : fermeture, sortie anormale = 0
Resultat : 1
Appel 2 : client 0 (refuse)
Ouverture de la ressource pour 0
Client invalide, sortie anticipee
ON-EXIT : fermeture, sortie anormale = 0
Resultat : 0
Les deux appels affichent « ON-EXIT : fermeture ». Dans le second, la procédure sort par return *off sans avoir atteint la fin, et le bloc est exécuté quand même. L'indicateur vaut 0 dans les deux cas : aucune erreur.
Exemple 2 : Sortie anormale et ordre d'exécution
**free
// ON-EXIT : sortie anormale (erreur) et ordre d'execution avec le MONITOR de l'appelant.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr moyenne packed(9:2);
total packed(9:2) const;
nombre packed(3:0) const;
end-pr;
dcl-s resultat packed(9:2);
monitor;
resultat = moyenne(1250.50 : 0);
snd-msg 'Moyenne : ' + %char(resultat);
on-error;
snd-msg 'MONITOR de l appelant : erreur, statut ' + %char(%status);
endmon;
resultat = moyenne(1250.50 : 4);
snd-msg 'Moyenne : ' + %char(resultat);
*inlr = *on;
dcl-proc moyenne;
dcl-pi *n packed(9:2);
total packed(9:2) const;
nombre packed(3:0) const;
end-pi;
dcl-s anormal ind;
snd-msg ' Calcul de ' + %char(total) + ' / ' + %char(nombre);
return total / nombre;
on-exit anormal;
snd-msg ' ON-EXIT : sortie anormale = ' + %char(anormal);
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Calcul de 1250.50 / 0
ON-EXIT : sortie anormale = 1
MONITOR de l appelant : erreur, statut 202
Calcul de 1250.50 / 4
ON-EXIT : sortie anormale = 0
Moyenne : 312.62
Le premier appel divise par zéro dans la procédure. Le ON-EXIT s'exécute en premier, avec l'indicateur à 1, et ensuite seulement le ON-ERROR du MONITOR de l'appelant, avec le statut 202. Le second appel, valide, termine avec l'indicateur à 0.
Le piège
L'ON-EXIT passe avant le traitement d'erreur de l'appelant. Dans le deuxième exemple, l'ordre affiché est : calcul, ON-EXIT (indicateur à 1), puis « MONITOR de l'appelant ». Le bloc de nettoyage ne doit donc pas dépendre de ce que l'appelant fera de l'erreur. Gardez-le court et sûr : une instruction qui échouerait dans le nettoyage ferait oublier l'erreur d'origine.