Modifier

La question

Aujourd'hui, j'ai vu passer la question suivante :

Comment passer dynamiquement un nombre variable de paramètres à une fonction ?

Si vous ne comprenez pas la question, voici un petit exemple :

Nous avons une fonction afficher_plusieurs_paramètres qui accepte 0, 1 ou plusieurs paramètres

PROCEDURE afficher_plusieurs_paramètres(*)
POUR i = 1 _A_ MesParamètres..occurrence
    Trace(MesParamètres[i])
FIN

Et nous souhaitons l'appeler, mais sans connaître à l'avance le nombre de paramètre. Une idée de code serait la suivante :

nb_paramètres est entier = 3
SELON nb_paramètres
    CAS 1 : afficher_plusieurs_paramètres(paramètre_1)
    CAS 2 : afficher_plusieurs_paramètres(paramètre_1, paramètre_2)
    CAS 3 : afficher_plusieurs_paramètres(paramètre_1, paramètre_2, paramètre_3)
    AUTRE CAS : afficher_plusieurs_paramètres()
FIN

L'idéal serait de pouvoir écrire le cas suivant :

CAS n : afficher_plusieurs_paramètres(paramètre_1, paramètre_2, ..., paramètre_n)

Mais ce n'est pas possible.

Et pourquoi ne pas utiliser un tableau ?

C'est vrai, on peut utiliser un tableau. Mais cela ne répond pas à la problématique. La question, c'est comment passer ces fichus paramètres de manière dynamique. On ne cherche pas à proposer une alternative.

La solution

La réponse est toute simple, il suffit d'utiliser la compilation dynamique, et deux options sont possibles :

La première utilise les fonctions ExecuteCode (on peut aussi utiliser Compile), la seconde, EvalueExpression (on peut aussi utiliser ExecuteCode et Compile mais le résultat sera plus verbeux) .

ExecuteCode, tout est compilé dynamiquement

Cette version est compatible avec la plupart des versions de WinDev (et si ce n'est pas le cas, vous pouvez utiliser la fonction Compile). L'idée est simplement de créer dynamiquement le code que l'on souhaite appeler.

On pourrait donc avoir le code suivant (en supposant que les variables paramètre1 et paramètre2 existent) :

paramètres est une chaine = "paramètre1, paramètre2" 
ExecuteCode(ChaineConstruit("afficher_plusieurs_paramètres(%1)", paramètres))

Et voilà, nous n'avons plus qu'à créer correctement le contenu de paramètres et nous pouvons indiquer les paramètres dynamiquement.

Mais cette solution a un inconvénient, c'est que si on renomme la fonction afficher_plusieurs_paramètres, le compilateur ne nous préviendra pas et nous aurons une erreur de compilation au moment de l'exécution. Heureusement, il existe une solution qui corrige ce problème.

EvalueExpression avec un tupple aka les valeurs de retour multiples

Il existe une solution plus simple et tout aussi efficace, c'est de combiner la fonction EvalueExpression avec un tupple. Dans WinDev, les tupples sont appelés des valeurs de retour multiples (L'inconvénient de ce nom, c'est que ça fait référence aux valeurs renvoyées par une fonction, mais pas aux valeurs reçues par une fonction).

Voici le même exemple que le cas précédent :

paramètres est une chaine = "paramètre1, paramètre2" 
afficher_plusieurs_paramètres(EvalueExpressiont("(" + paramètres + ")"))

Deux avantages :

  • Le code est lisible.
  • La fonction afficher_plusieurs_paramètres est détectée par le compilateur. Si on modifie le nom de cette fonction, WinDev signalera une erreur de compilation.

Pour comprendre cet exemple, il faut savoir que l'on peut passer à une fonction recevant x paramètres le résultat d'une fonction renvoyant x valeurs.

Voici un petit exemple :

afficher_plusieurs_paramètres(lister_paramètres())  // Affiche a + rc + b + rc + c

PROCEDURE lister_paramètres()
RENVOYER ("a", "b", "c")

Le secret, pour renvoyer un tupple, c'est de ne pas oublier les parenthèses sur la ligne du RENVOYER.

Et EvalueExpression, ça fait quoi exactement ?

EvalueExpression est une fonction qui prend une expression compatible WLangage®, elle l'exécute dynamiquement puis renvoie ainsi la nouvelle valeur créée. En ajoutant les parentèses, EvalueExpression crée donc un tupple que la fonction afficher_plusieurs_paramètres peut consommer.

Pour finir

Et voilà, si vous connaissez le nombre et le nom de vos paramètres, vous pouvez désormais créer et appeler des fonctions avec un nombre variable de paramètres.

J'espère que cet article vous a plu. N'hésitez pas à laisser vos remarques dans la partie commentaire.

Article suivant Article précédent

Blog Comments powered by Disqus.