Page 1 sur 1

[Tuto] Attention avec les variables

Posté : mar. 12 sept. 2017 13:25
par Numeric
IsDeclared ( )
Parmi les fonctions internes d’AutoIt, il y en a qui ne semblent pas prouver leur utilité au grand jour. Plusieurs raisons expliquent cela. En effet, soit il existe d’autres fonctions qui font mieux les tâchent que ces dernières sont censées faire, soit les tâchent que ces dernières font ne sont pas vraiment utiles, ou bien tout simplement ces dernières ne figurent pas dans le dictionnaire de bon nombres de programmeurs. Dans cette présente, Je vous propose de revenir sur une fonction qu’on rencontre moins dans les codes AutoIt. Une fonction dont le nom même pourrait laisser croire qu’elle n’est pas vraiment nécessaire en soit, à partir du moment où nous sommes maitre de ce que nous faisons dans notre code. Il s’agit de la fonction IsDeclared ( ). Que fait-elle exactement ? Est-elle vraiment utile ? Où bien indispensable? Et bien plus d’un seront étonnés par la suite de cette étude.

1. Fonctionnalité
La fonction isDeclared () permet de vérifier la déclaration d’une variable. C’est à dire de voir s’il y a de la mémoire réservée au nom de la variable qu’on veut tester. Cette variable peut ne pas forcement exister mais déclarée. Généralement avec un code aéré et court, l’utilisation de cette fonction semble ne pas être indispensable. Car nous pouvons déclarer et assigner à tout moment une valeur à une variable, sans vraiment craindre un conflit ou une absorption de valeur. Mais cependant, je me dois de vous rappeler que l’utilisation des variables (ce qui est indispensable en programmation) comporte cependant des risques en ce qui concerne l’intégrité de leurs valeurs.

2. Le principe d’encapsulation
Dans les langages Orienté Objet, il existe une méthode pour protéger une variable de l’extérieur d’un objet donné. C’est-à-dire que vous ne pouvez pas porter atteinte à l’intégrité de cette dernière, donc vous ne pouvez pas par mégarde modifier sa valeur. Cette méthode c’est l’encapsulation. Mais cependant plusieurs langages de programmation n’en disposent pas pour leurs développeurs. Et AutoIt en fait partie pour le moment. Donc AutoIt n’offre pas encore à ses développeurs les moyens pour assurer l’intégrité de certains types de variables qu’ils déclarent dans leurs codes. D’où la nécessité de vérifier l’existence et la déclaration d’une variable avant de l’utiliser pour ne pas empiéter la valeur d’une autre portant le même nom.
Bien que les langages qui n’encapsulent pas leurs données aient développé des méthodes pour limiter les dégâts d’usurpation d’identités des variables, Cependant ces méthodes n’en dissipent pas pour autant les risques.
AutoIt a pour ce fait misé sur la portée des variables. C’est-à-dire qu’une variable peut avoir une portée Global ou Local selon sa déclaration. Donc une variable locale Local ne sera Déclarée que localement. Elle n’aura d’existence que dans sa localité (Exemple une variable locale déclarée dans une fonction, n’existe que dans celle-ci ). Mais une variable globale Global est connue à n’importe quel endroit de votre code. Que ce soit à l’intérieur d’une fonction, et même dans un autre fichier de code à condition que celui-ci soit inclus dans le fichier en cours d’exécution.

3. Le problème
Pour chaque déclaration d’une variable, vous utilisez un espace mémoire. Imaginez que vous ayez besoin d’une variable Globale tout le long de votre code (30 fois par exemple). Si vous la déclarée 30 fois, vous aurez utilisé 30 espaces mémoires. Et aussi si votre fichier dans lequel vos variables ont été déclarées est inclus 3 fois, dans un autre fichier code, alors vos variables auront pris 30x3 espaces mémoires. Alors que si vous la déclariez une seule fois globalement, elle aurait utilisé seulement 3 espaces mémoires (une fois à chaque fois que le fichier dans lequel elle est déclarées est inclus dans votre code). Mais cependant si vous déclarez Global votre variable et qu’à un certain moment de votre code vous déclariez par mégarde une autre variable de même nom. Alors vous usurpez l’identité de votre première variable si celle-ci n’a pas l’attribut d’une constante.

4. Un exemple concret
Avec les UDF d’AutoIt, lorsque vous créez un contrôle, il existe une variable global, un tableau qui permet de calculer pour vous l’ID du contrôle. Car la fonction qui crée les fenêtres en a besoin. Cette variable Globale, ne doit en aucun cas être modifiée par les utilisateurs, et elle ne peut pas non plus être déclarée globale –constante car elle varie mais avec une logique donnée. Donc si dans votre code vous utilisez une variable de même nom que celle dont nous parlons, alors vous usurpez l’identité cette derniere.ET risquez même d’obtenir des résultats inattendus. Mais rassurez-vous, ce problème ne concerne que les UDF et non pas les fonctions internes d’AutoIt. Car les variables utilisées par les fonctions internes d’AutoIt sont encapsulées. Leurs intégrités sont préservées. Referez-vous à l’exemple 1 pour constater ce fait.
#Region EXEMPLE 1

#include <GuiListView.au3> ; Ceci nous apporte un message de la variable $__g_aUDF_GlobalIDs (reference numero 1)
; Cette variable est un tableau qui genere les ID des controles d'UDF...
; La fonction _GUICtrlListView_Create en a besion, car c'est elle qui genere son ID qui sera associé à son handle,
; Et que nous pourons rappeler plus tard grace à la fonction _WinAPI_GetDlgCtrlID($hWnd_ListView)

;===============Probleme=========================
;Pour verifier la source d'erreur dans mon code, je declare un variable globale.

Global $__g_aUDF_GlobalIDs_Used = "pas de valeur" ;voir plus haut quand nous avons inclus le fichier UDF GuiListView.au3
;Nous ignorons que nous avons besoin de cette meme variable pour d'autres fins.

;Premier changement logique de ma variable globale, je veux verifier le type String d'une variable
Local $MonString = "AutoIt"
If IsString($MonString) Then $__g_aUDF_GlobalIDs = "valeur de String" ;Nous avons une nouvelle valeur associee à notre variable $__g_aUDF_GlobalIDs

MsgBox(48, "Verification de valeur", "La valeur de ma variable globale est : " & $__g_aUDF_GlobalIDs)
;Jusque la il n'ya pas de probleme.

;Nous avons maitenant besoin de notre GUI et de notre fameux controle listview, controle pour lequel nous avons d'ailleurs inclus le fichier <GuiListView.au3>
;Nous rencontrons un probleme.Car nous avons usurpé a notre insu l'identité de la variable $__g_aUDF_GlobalIDs. qui est utilisee par la fonction de creation de la listview

Global $Form1 = GUICreate("Form1", 442, 166, 192, 124)
Global $Edit1  = _GUICtrlListView_Create($Form1, "   ", 128, 32, 185, 89)
GUISetState()

Do
Until GUIGetMsg() = -3

#EndRegion EXEMPLE 1

5. La Solution appropriée
Les UDF d’AutoIt respectent un certain nombre de principe. Parmi les quels nous avons la nomination des variables et celle des fonctions. Pour ce qui est des variables, elles comportent des tirets sur mesure «Global $____iMaVariable = 1» donc la solution 1 pour éviter d’empiéter la valeur d’une variable d’UDF c’est d’éviter les tirets sur mesures présentés ci-dessus. Mais malheureusement cette solution n’est pas efficace à 100%. Ce qui nous fait envisager une autre solution. Et celle-là c’est la plus efficace et elle l’est à 100%. C’est la vérification d’une éventuelle précédente déclaration d’une variable avant de la déclarer. Et cette vérification, AutoIt nous permet de la faire grâce à sa fonction interne isDeclared. Grace à cette fonction, nous allons éviter de corrompre les messagers de longues routes que sont les variables globales.
6. Utilisation de la fonction IsDeclared
L’exemple 2 donnes plus de détails sur l’utilisation de cette fonction.
#Region EXEMPLE 2

;Comment utiliser la fonction isDecared?
;Le principe :

Local $Fonction_Declaree = "Numeric" ;Declaration de ma fonction.

If IsDeclared("Fonction_Declaree") Then MsgBox(48, '', 'La variable  $Fonction_Declaree est déclarée') ;remarque : je ne met plus le '$' au nom de la variable
;si je veux verifier sa declaration.

;Pour retourner la valeur d'une variable dont nous avons testé la declaration nous utilisons la fonction Eval()
;EXEMPLE
If IsDeclared("Fonction_Declaree") Then MsgBox(48, "Verification et extraction de la valeur d'une variable", "La variable $Fonction_Declaree est déclarée et sa valeur est " & Eval("Fonction_Declaree"))

;Remarque IsDeclared et Eval utilisent les noms des variables sans le symbole "$" devant.
;il faudra faire attention à écrire le nom correct.

#EndRegion EXEMPLE 2

7. Conclusion
En incluant un fichier UDF, dans votre code, vous augmentez le risque d’empiéter involontairement la valeur d’une variable s’y trouvant. Et cela pourrait fausser vos résultats. Le meilleur des cas serait une erreur vous le signalant comme dans notre exemple 1, sinon dans le pire des cas, vous n’avez pas d’erreur visible mais un mauvais résultat. Ce perpétuel risque de double déclaration d’une variable peut être évité par l’utilisation d’une fonction simple d’usage qu’est la fonction IsDeclared ( ).