Les procédures internes introduites dans le WLangage en version 20 ont permis de simplifier grandement l'écriture de traitements, en évitant d'avoir systématiquement recours à une procédure locale.
Voici un exemple concret. Historiquement, lorsqu'un traitement avait besoin d'une call-back, on devait nécessairement ajouter une procédure locale à la fenêtre. Prenons pour cette illustration un menu contextuel d'une application qui affiche les précédents documents ouverts :
Avec ce code, pour que la sélection d'une option ajoutée dynamiquement au menu par la fonction MenuAjouteOption fasse l'ouverture, il faut une procédure locale :
![](/PCSBLOGS_WEB/ext/content-upload/post281474976710865_cae6315935734c8aa9a828fe7c75b254_mceclip0.png?20200310124531390)
Grâce aux procédures internes, la procédure locale n'est plus la seule possibilité. Elle restera avantageuse pour des traitements conséquents. Mais comme ici ou l'action est réduite, il est bien plus lisible de supprimer la procédure locale, et d'ajouter la procédure interne au niveau du code qui l'utilise :
![](/PCSBLOGS_WEB/ext/content-upload/post281474976710865_70b5be5ac0ca474bb55f7d01f24d2159_mceclip0.png?20200310125830015)
A partir de la version 25, le WLangage permet d'utiliser une lambda ("lambda fonction") qui est une écriture plus concise des procédures internes. Dans cet exemple, le traitement est encore raccourci, la procédure interne disparaît !
![](/PCSBLOGS_WEB/ext/content-upload/post281474976710865_adfa264b8e3c4a45b739f266ac373e79_blobid0.png?20200310130505921)
En terme d'exécution le résultat sera identique. Le choix sera surtout en lien avec les habitudes de programmation de chaque développeur, car là il y en a vraiment pour tous les goûts !
Pour une concision totale, Filter, Map et Agrège sont également disponibles. L'écriture d'opérations sur les tableaux est réduite à sa plus simple expression. Voici un exemple de code autonome à copier/coller dans un bouton pour apréhender ces syntaxes. Le code est majoritairement constitué de traces explicatives, les opérations étant toutes sur une seule ligne !
tab1 est un tableau d'entiers = [1, 2, 3, 4, 5] tab2 est un tableau d'entiers = [3, 5]
tab3 est un tableau d'entiers
tab3 = tab1.Filter(x => (TableauCherche(tab2,tcLinéaire,x) = -1 ) )
Trace("Tableau tab3 les éléments de tab1 qui ne sont pas dans tab2...") Trace("tab1 "+TableauVersChaîne(tab1, ", ")) Trace("tab2 - "+TableauVersChaîne(tab2, ", ")) Trace("tab3 = "+TableauVersChaîne(tab3, ", "))
tab1 = [1, 2, 3, 4, 5, 6, 7, 8 , 9, 10] tab3 = tab1.Filter( x => EstImpair(x)) Trace(RC+RC+"Tableau tab3 contient les nombres impairs du tableau tab1...") Trace("tab1 "+TableauVersChaîne(tab1, ", ")) Trace("tab3 = "+TableauVersChaîne(tab3, ", "))
nTotal est un entier = tab1.Filter( x => EstImpair(x)).Agrège( (valeur, masomme) => {RENVOYER valeur + masomme}, 0) Trace(RC+RC+"Somme des nombres impairs du tableau tab1 ...") Trace("tab1 " + TableauVersChaîne(tab1, ", ")) Trace("Somme = " + nTotal)
tabCelcius est un tableau de réels = [36.5, 37, 37.5, 38, 39] tabFahrenheit est un tableau de réels tabFahrenheit = Map(tabCelcius, CelciusToFahrenheit) Trace(RC+RC+"Conversion Celsius Fahrenheit ...") Trace("tabCelcius " + TableauVersChaîne(tabCelcius, ", ")) Trace("tabFahrenheit " + TableauVersChaîne(tabFahrenheit, ", "))
PROCEDURE INTERNE CelciusToFahrenheit( t ) RENVOYER Conversion(t,"degré Celsius", "degré Fahrenheit") FIN
tabFahrenheit.SupprimeTout() tabFahrenheit = Map(tabCelcius, t=>{RENVOYER Conversion(t,"degré Celsius", "degré Fahrenheit")}) Trace(RC+RC+"Conversion Celsius Fahrenheit ...") Trace("tabCelcius " + TableauVersChaîne(tabCelcius, ", ")) Trace("tabFahrenheit " + TableauVersChaîne(tabFahrenheit, ", "))
|
|
< Retour |
7 commentaires
![//www.gravatar.com/avatar/e46000841ed8ef4972625dc5bfdb1416?s=100&d=//www.gravatar.com/avatar/00000000000000000000000000000000](../../) | MindSoft 11/03/2020 - 11:28 - Répondre - En attente de modération A ce jour, les nouvelles fonctions Filter, Map et Agrège ne sont pas encore présentes dans l'aide en ligne. Merci Guillaume pour l'illustration pratique. |
|
| |
| ![//www.gravatar.com/avatar/822fb7dc219cca9d138967fdaaaba2e2?s=100&d=//www.gravatar.com/avatar/00000000000000000000000000000000](../../) | Mathieu Chevallier 22/05/2020 - 17:23 - Répondre - En attente de modération Les lambda c'est vraiment cool mais peux-t'on créer des procédures avec des fonctions en paramètre ? Avec ça on pourrait passer nos lambda à nos procédures ou à nos objets... |
|
| |
| ![//www.gravatar.com/avatar/822fb7dc219cca9d138967fdaaaba2e2?s=100&d=//www.gravatar.com/avatar/00000000000000000000000000000000](../../) | Mathieu 10/07/2020 - 22:31 - Répondre - En attente de modération Bonjour Guillaume, est-il possible d'implémenter ou de dériver une classe ou une interface afin de pouvoir avoir mon propre conteneur dans lequel je peux implémenter mes propres méthodes map(), filter() etc... ? Je pourrais avec ça passer des lambda fonctions. Par exemple votre objet tableau implémente t-il une interface pour les méthodes map et filter ? Autrement le concept d'interface fonctionnelle existe -t'il ? cela me permettrait de créer des méthodes dans lesquelles je peux passer des lambda. |
|
| |
| ![/PCSBLOGS_WEB/ext/images/pcsoft_avatar.png](../../) | Guillaume Bayle 13/07/2020 - 09:33 - Répondre - En attente de modération Bonjour, cette possibilité de surcharge n'est pas encore proposée, mais elle est suggérée à notre équipe développement ! J'espère que les implémentations nécessaires pourront être planifiées rapidement. Bons développements ! |
|
| |
| ![/PCSBLOGS_WEB/ext/images/pcsoft_avatar.png](../../) | Guillaume Bayle 13/07/2020 - 09:34 - Répondre - En attente de modération Bonjour, cette possibilité de surcharge n'est pas encore proposée, mais elle est suggérée à notre équipe développement. J'espère que les implémentations nécessaires pourront être planifiées rapidement. Bons développements ! |
|
| |
| ![/PCSBLOGS_WEB/ext/images/pcsoft_avatar.png](../../) | Guillaume Bayle 13/07/2020 - 09:35 - Répondre - En attente de modération Bonjour, cette possibilité de surcharge n'est pas encore proposée, mais elle est suggérée à notre équipe développement. J'espère que les implémentations nécessaires pourront être planifiées rapidement. Bons développements ! |
|
| |
| ![//www.gravatar.com/avatar/79676f533d594e1748cbe76f30a7b1a3?s=100&d=//www.gravatar.com/avatar/00000000000000000000000000000000](../../) | Eric COUTIER 22/01/2021 - 17:04 - Répondre - En attente de modération Bonjour, Ce serait encore plus fort si on pouvait faire des filter sur une chaine de caractères (donc il faudrait avoir une procédure qui renvoie un tableau de chaines contenant tous les caractères d'une chaîne) On pourrait alors traiter une telle chaîne par les lambda: Exemple: n'avoir que les chiffres d'une chaîne: MaChaine.VersUnTableau().Filtre(c => (c DANS (1,2,3,4,5,6,7,8,9,0)).VersChaine("") |
|
| |
| |
|
| |
| | |