|
|
|
|
|
- Principe
- Déclaration et appel des procédures internes
- Exemple
- Caractéristiques des procédures internes
- Utilisation en callback
- Paramètre de type Procédure interne
- Accès aux variables depuis une procédure interne
- Imbrication de procédures internes
- Procédures internes soeurs
- Appels récursifs
- Paramètres nommés
- Compilation dynamique
- Procédure interne et attributs d'extension
- Cas particulier : Utilisation de procédures internes avec des fonctions asynchrones
- Limitations
De nombreuses fonctionnalités nécessitent une procédure appelée une ou plusieurs fois au travers d'une fonction du WLangage (également appelée "Callback"). Par exemple, les fonctions suivantes sont dans ce cas : fListeFichier, ArbreListeFils, AlbumSélecteur en iOS, etc. Il est nécessaire de créer une procédure pour ces fonctions, mais de nombreux inconvénients apparaissent : - Perte de la localité du code : Il n'est pas possible de voir l'algorithme final dans son ensemble. Il est nécessaire de faire des aller-retour entre le code appelant et la procédure WLangage.
- Difficulté de partage d'informations avec la procédure WLangage : Il est en général nécessaire d'utiliser des variables globales (pour passer des paramètres à la callback ou récupérer les résultats).
Dans ce cas, les procédures internes permettent de simplifier l'écriture des fonctionnalités à callback et de simplifier les problèmes posés par l'utilisation d'une procédure classique. Déclaration et appel des procédures internes La déclaration d'une procédure interne se fait directement dans le code d'un traitement existant (traitement associé à un champ, procédure de fenêtre, procédure globale ou méthode de classe, ...). La syntaxe est la suivante :
PROCEDURE INTERNE <Nom de la procédure>() <Code de la procédure> FIN Remarques : - Les procédures internes doivent être déclarées dans le traitement dans lequel elles sont utilisées.
- L'assistance à la saisie des paramètres est activée : une bulle d'aide précisant le type du paramètre attendu est affichée lors de la saisie de l'appel de la procédure interne.
- Le code du traitement situé avant et après le code de déclaration de la procédure interne est exécuté en séquence : le code de la procédure interne n'est pas exécuté.
Exemple :
PROCÉDURE INTERNE MaProcédureInterne()
FIN
- Il est possible d'appeler directement une procédure interne par son nom, comme pour une procédure classique. Cet appel peut être placé avant ou après la déclaration de la procédure interne.
Exemple :
MaProcédureInterne()
PROCÉDURE INTERNE MaProcédureInterne()
FIN
MaProcédureInterne()
Il est ainsi possible d'obtenir un code plus simple à lire. - Les exceptions provoquées par les procédures internes peuvent être traitées à l'extérieur de la procédure interne.
Caractéristiques des procédures internes Utilisation en callback La procédure interne peut être utilisée dans une fonction du WLangage qui attend une procédure WLangage en paramètre (comme fListeFichier, ArbreListeFils, ...). Attention : Dans ce cas, le paramètre correspondant au nom de la procédure interne doit correspondre directement au nom de la procédure interne (le nom de la procédure ne doit pas être entre guillemets). Ne pas faire :
Res = ArbreListeFils(ARBRE_RecetteTV, "Recettes" + TAB + "Desserts", "DérouleTout")
PROCÉDURE INTERNE DérouleTout(ARBRE_RecetteTV, CheminFils, FilsTrouvé, Niveau, Pointeur)
...
FIN
Faire :
Res = ArbreListeFils(ARBRE_RecetteTV, "Recettes" + TAB + "Desserts", DérouleTout)
PROCÉDURE INTERNE DérouleTout(ARBRE_RecetteTV, CheminFils, FilsTrouvé, Niveau, Pointeur)
...
FIN
Paramètre de type Procédure interne La procédure interne peut être utilisée comme paramètre dans une procédure. Dans ce cas le type du paramètre sera de type "Procédure". Exemple :
PROCÉDURE INTERNE MaProcédureInterne()
FIN
MonAutreProcédure(MaProcédureInterne)
PROCÉDURE MonAutreProcédure(p est une procédure)
p()
Accès aux variables depuis une procédure interne Les variables déclarées dans le même traitement que la déclaration de la procédure interne peuvent être appelées dans la procédure interne. Il n'est plus nécessaire d'utiliser des variables globales. Ce concept est appelé "Closure". Exemple :
sListeElément est une chaîne
sSéparateur est une chaîne = RC
ArbreListeFils(ARBRE_ChampArbre, "", MaProcédureInterne)
PROCÉDURE INTERNE MaProcédureInterne(NomArbre, Branche)
sListeElément += [sSéparateur] + Branche
FIN
Imbrication de procédures internes Les procédures internes peuvent être imbriquées. Chaque procédure interne peut accéder aux variables des procédures qui l'incluent. Exemple :
VariableExterne est un entier
Trace(VariableExterne)
MaProcédureInterne1()
PROCÉDURE INTERNE MaProcédureInterne1()
VariableInterne1 est un entier
Trace(VariableExterne + VariableInterne1)
MaProcédureInterne2()
PROCÉDURE INTERNE MaProcédureInterne2()
VariableInterne2 est un entier
Trace(VariableExterne + VariableInterne1 + VariableInterne2)
FIN
FIN
Procédures internes soeurs Deux procédures internes présentes dans la même procédure peuvent s'appeler entre elles (procédures internes soeurs). Exemple :
PROCÉDURE INTERNE MaProcédurePrincipale()
PROCÉDURE INTERNE MaProcédureInterne1()
...
FIN
PROCÉDURE INTERNE MaProcédureInterne2()
...
MaProcédureInterne1()
FIN
FIN
Appels récursifs Une procédure interne peut s'appeler elle-même de façon récursive. Paramètres nommés Si une procédure interne possède des paramètres avec des valeurs par défaut, il est possible d'appeler la procédure interne en nommant ses paramètres. Deux syntaxes sont possibles : - Paramètres nommés monolignes,
- Paramètres nommés multilignes.
Compilation dynamique Il est possible d'utiliser une procédure interne dans un code compilé dynamiquement (avec la fonction Compile par exemple). Exemple :
lsCode est chaîne = [
// Code compilé dynamiquement
sListeElément est une chaîne
sSéparateur est une chaîne = RC
ArbreListeFils(ARBRE_ChampArbre, "", MaProcédureInterne)
PROCEDURE INTERNE MaProcédureInterne(NomArbre, Branche)
sListeElément += [sSéparateur] + Branche
FIN
]
lsRésultat est chaîne
lsRésultat = Compile("MaProc",lsCode)
Procédure interne et attributs d'extension Les attributs d'extensions peuvent être utilisés avec les procédures internes. Par exemple, un traitement unique peut exécuter une procédure interne dans un thread secondaire pour ne pas être bloquant, puis appeler une seconde procédure dans le thread principal pour mettre à jour l'interface. Exemple :
ExécutionAsynchrone()
PROCÉDURE INTERNE ExécutionAsynchrone() <thread>
ThreadPause(5 s)
AprèsExécutionAsynchrone()
FIN
PROCÉDURE INTERNE AprèsExécutionAsynchrone() <thread principal>
Trace("Terminé ...")
FIN
Cas particulier : Utilisation de procédures internes avec des fonctions asynchrones Les procédures internes peuvent être utilisées comme "Callback" pour des fonctions asynchrones. ATTENTION : Dans ce cas, le code situé après l'appel de la fonction utilisant une procédure WLangage asynchrone sera exécuté AVANT le code de la procédure Interne. Exemple : Dans cet exemple pour WINDEV Mobile, le code situé après la fonction AlbumSélecteur sera exécuté AVANT la procédure interne. La procédure interne sera appelée lorsque l'utilisateur aura validé le sélecteur.
AlbumSélecteur(albumImage, SélectionPhoto)
PROCÉDURE INTERNE SélectionPhoto(sCheminImage)
IMG_ChampImage = sCheminImage
FIN
- Une procédure interne ne peut pas avoir le même nom que la ou les procédures qui la contiennent.
- Deux procédures internes de même niveau ne peuvent pas avoir le même nom, même si elles sont déclarées dans des blocs de code différents (SI ALORS SINON, ...).
- Les procédures internes ne sont pas disponibles en compilation dynamique.
- Il n'est pas possible d'automatiser l'exécution d'une procédure interne.
- La gestion automatique des erreurs n'est pas disponible sur les procédures internes.
- Si l'option "Portée des variables locales limitée au bloc courant" est activée dans l'onglet "Compilation" de la description du projet, la déclaration de procédures internes utilisant des variables "avec limitation de portée" entraînera une erreur de génération. Exemple :
- le code suivant provoque une erreur de compilation :
PROCÉDURE MaProcedure()
SI MaCondition ALORS
str est une chaîne
PROCÉDURE INTERNE ma_proc_interne()
str = "truc"
FIN
FIN
- Pour corriger ce code, il est nécessaire de ne pas déclarer la variable dans l'instruction SI :
PROCÉDURE MaProcedure()
str est une chaîne
SI MaCondition ALORS
PROCÉDURE INTERNE ma_proc_interne()
str = "truc"
FIN
FIN
En Java et Android, il est recommandé de toujours déclarer les procédures internes dans la portée de la procédure elle-même. Ainsi, si des variables non déclarées sont utilisées, des erreurs de compilation seront affichées.
Documentation également disponible pour…
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|