[Tuto] Réflexion en Autoit

Espace contenant des tutoriels divers concernant AutoIt.
Règles du forum
.

Tutoriel "La programmation avec Autoit" : https://openclassrooms.com/fr/courses/1 ... vec-autoit
Répondre
Avatar du membre
Iste
Modérateur
Modérateur
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

[Tuto] Réflexion en Autoit

#1

Message par Iste » ven. 14 janv. 2011 11:43

Définition :
Wikipedia a écrit :En programmation informatique, la réflexion est la capacité d'un programme à examiner, et éventuellement à modifier, ses structures internes de haut niveau (par exemple ses objets) lors de son exécution.
La définition n'est pas facile à saisir, mais elle me semble exacte.
Pour faire plus simple, la réflexion, c'est la capacité a un programme de pouvoir, par exemple, lire le contenu d'une variable grace a son nom, mais aussi de pouvoir modifier son contenu de la même manière.
Le fait de lire du contenu par réflexion s'appelle l'introspection.
Le fait d'écrire du contenu par réflexion s'appelle l'intercession.

Les fonctions en Autoit :


Les fonctions liées à la réflexion mises a notre disposition sont :
-Eval()
-IsDeclared()
-Assign()
-Call()
-Execute()

Eval() et IsDeclared() font de l'introspection, Assign() et Call() de l'intercession et Execute() est un peu mixte.

Utilisation :


La fonction Eval() :
Cette fonction retourne la valeur de la variable dont le nom est passé en paramètre :

Code : Tout sélectionner

$maVariable = 5
Eval("maVariable")
Eval() retourne 5

La fonction IsDeclared() :
Pour utiliser Eval(), il est bon de savoir si la variable existe avant. IsDeclared() permet de savoir par un nom de variable si elle existe, et si elle est local ou non (voir les Scope)

Code : Tout sélectionner

$maVariable = 5
If IsDeclared("maVariable") Then
    Eval("maVariable")
EndIf
Ce code récupère la valeur de la variable "maVariable" si elle existe.

La fonction Assign() :
Cette fonction permet d'assigner une valeur a une variable, et de la créer si elle n'existe pas.

Code : Tout sélectionner

Assign("variable", "Hello", 2)
MsgBox(0,"test",$variable)
Attention !
Scite va lancer un message d'erreur a la compilation, car pour lui $variable n'existe pas. Mais si l'on compile quand même, tout fonction car le 3em paramètre passé a Assign() demande la création de la variable.

La fonction Call() :
Call() permet d'appeler une fonction et de lui passer des paramètres. Call() retourne la valeur de retour de la fonction appelée.

Code : Tout sélectionner

$maVariable = 0
Call("set",10)
MsgBox(0,"test",$maVariable)

Func set($param)
    $maVariable = 5 + $param
EndFunc
$maVariable vaut 15.


La fonction Execute() :
La fonction Execute() est bien plus puissante que les autres. Elle permet d'exécuter un bout de code et renvoie ce que le code retourne. Ce code est envoyé sous forme de chaine de caractères une fois de plus.

Code : Tout sélectionner

$maVariable = 4
$autre = Execute("$maVariable + 5")
$autre devient égale a 9.
Mais l'ont peut aussi faire des choses bien plus intéressantes en demandant a Execute() d'évaluer une fonction

Code : Tout sélectionner

$maVariable = 4
$autre = Execute("Assign('maVariable',5)")
MsgBox(0,'test',$maVariable)
$maVariable a changé de valeur pour prendre 5.
Attention !

Code : Tout sélectionner

[code]$maVariable = 0
Execute("$maVariable = 5")
[/code]Ne fonctionne pas. Il faut donner a Execute() quelque chose a évaluer = quelque chose qui retourne une valeur.
On peut utiliser Execute() à la manière d'Eval()

Code : Tout sélectionner

$maVariable = 4
$autre = Execute("$maVariable")
MsgBox(0,'test',$autre)
Ou encore de Call()

Code : Tout sélectionner

$maVariable = 0
Execute("set(10)")
MsgBox(0,"test",$maVariable)

Func set($param)
    $maVariable = 5 + $param
EndFunc
Mais comme l'on peut évaluer une fonction, on peut tout faire avec. Il suffit d'appeler une fonction "à évaluer" qui va faire ce que l'on attend.

Cas d'utilisation :


Voici des exemple de cas ou ces fonctions peuvent être utile. Je précise bien "utile" car l'on peut en coller un peu partout dans un script sans que leur appel soit pertinent !

Eval() :
Eval() fonctionne de paire avec Assign(). Dans le cadre ou l'on doit créer des variables dynamiquement, c'est la solution pour récupérer leur valeur.
Ex : J'ai un fichier text contenant des paires clef/valeur, je peux créer des variables au nom de la clef contenant la valeur. Plus loin dans le script, ou même de manière externe grace à Execute(), je n'aurai qu'a préciser le nom de la clef pour en obtenir la valeur. Je peux donc avoir un autre fichier texte contenant que des clef, et par magie, demander à Autoit d'additionner leur valeur contenue dans l'autre fichier texte !

IsDeclared() :
Il s'agit la surtout d'une sécurité pour les Eval(), mais l'ont peut trouver d'autre utilités.
Dans notre exemple, ci dessus, apres lecture du 1er fichier texte, IsDeclared($name) permet de savoir si une clef est présente.

Assign() :
Restons toujours dans le même exemple.
Âpres avoir récupéré toute les clef/valeurs, je souhaite leur appliquer une transformation, Assign() me permet donc d'après le nom de la clef de modifier la variable.

Call() :
Imaginons un logiciel de configuration possédant plusieurs fonctions qui doivent être appelée ou non. l'on peut passer la liste des fonctions à appeler en paramètre, une boucle For et Call() se chargeront du reste !

Execute() :
Les cas d'utilisations de cette fonctions sont trop vaste pour essayer de les résumer rapidement. Pensez juste cela :
Vous pouvez demander à votre programme de faire quelque chose non présent dans le code, après la compilation.
Juste cette phrase permet d'imaginer la puissance de cette fonction !

Conclusion :


La réflexion est une chose extrêmement puissante qui peut rendre les programme beaucoup plus propre et puissant, a condition d'être bien utilisé !!
Réfléchissez donc à la pertinence de leur utilisation avant de les taper, car elles peuvent aussi rendre votre code très lourd et très crade !


Un petit exemple pour montrer la puissance d'Eval, Assign, IsDeclared, mais aussi les risques !
liste.txt contient une liste de personnes et leur salaire.
aug.txt est une liste de personne a augmenter (marquez "aug.txt" dans l'inputbox)
Pour faire planter le truc, essayez d'augmenter une variable du script :)
Fichiers joints
reflect exemple.zip
Exemple simple
(1.52 Kio) Téléchargé 352 fois
reflect exemple.zip
Exemple simple
(1.52 Kio) Téléchargé 352 fois
Signez ici

Avatar du membre
Fish
Niveau 5
Niveau 5
Messages : 178
Enregistré le : sam. 23 oct. 2010 18:28
Localisation : Devant mon ordinateur.
Contact :
Status : Hors ligne

Re: [Tuto] Réflexion en Autoit

#2

Message par Fish » ven. 14 janv. 2011 17:51

Merci iste, sympa le tutoriel même si je trouve qu'un peut plus de couleurs ne ferait pas de mal... :D
Cordialement,
Fish-panai.
P.S (Pas Salé): Vive le poisson pané.

Avatar du membre
pop45
Membre émérite
Membre émérite
Messages : 251
Enregistré le : dim. 30 août 2009 15:18
Status : Hors ligne

Re: [Tuto] Réflexion en Autoit

#3

Message par pop45 » ven. 14 janv. 2011 18:15

Bon je vais juste te signaler une petite chose qui me parais bizarre :)
Mais sinon ton petit tuto est très bien
Iste a écrit : Mais l'ont peut aussi faire des choses bien plus intéressantes en demandant a Execute() d'évaluer une fonction

Code : Tout sélectionner

$maVariable = 4
$autre = Execute("Assign('maVariable',5)")
MsgBox(0,'test',$maVariable)
$maVariable a changé de valeur pour prendre 5.
Je vois aucune trace de la fonction eval() qui sert pourtant a évaluer?
Soit tu t'est trompé en voulant dire assigner, soit en voulant mettre la fonction eval() a la place de assign()

Sinon pour le reste c'est très bien
Dailleur quand j'ai lus la premier fois : "la réflexion est la capacité d'un programme à examiner, et éventuellement à modifier, ses structures internes de haut niveau (par exemple ses objets) lors de son exécution.", j'ai penser que tu parlais d'une IA :lol:
Cordialement Pop45
Veuillez agrée nos sentiment les plus distinguer, soyez assurer de mon entièr et amical collaboration, bien a vous pour toujours et a jamais dans l'unique but de servir l'espérance de votre satisfaction.

Avatar du membre
Iste
Modérateur
Modérateur
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [Tuto] Réflexion en Autoit

#4

Message par Iste » ven. 14 janv. 2011 18:58

@Fish ouaip, j'aurai du autoiter le code, je suis pas fan des couleurs moi ^^'

@pop45 :
doc a écrit :Return Value

Success: Returns the value of the evaluated expression.
Donc pas de rapport directe avec Eval, juste que Eval évalue une variable, et Execute() exécute et évalue une expression.

Et non, pas d'IA ici, l'introspection en programmation est loin de celle en psychologie ^^

Edit : ajout d'un exmple simple pour eval et assign. Testez d'augmenter "FILE_LIST" :)
Signez ici

lesolutionneur
Niveau 7
Niveau 7
Messages : 368
Enregistré le : ven. 09 déc. 2011 11:25
Status : Hors ligne

Re: [Tuto] Réflexion en Autoit

#5

Message par lesolutionneur » mar. 03 janv. 2012 21:24

Merci pour le tuto même si je n'ai pas compris l'intérêt des fonctions sauf IsDeclared()

À quoi ça sert de faire assign(variable, 3)
Si on peux faire $variable = 3 ?

Pareil pour tout le reste : je ne vois pas la différence avec leurs "synonymes"

Avatar du membre
Iste
Modérateur
Modérateur
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [Tuto] Réflexion en Autoit

#6

Message par Iste » mar. 03 janv. 2012 22:18

Bah c'est justement le principe de la réflexivité, on peut s'en passer ou n'utiliser que ca.
C'est un peu comme les fonction récursive, on est pas obligé de faire ainsi, mais des foi, c'est vachement plus simple pour notre cerveau.
Donc imaginons une appli avec x boutons ou x label qui dépendrait d'un fichier ini, on peut facilement s'en sortir sans devoir utiliser des tableau dont on risque de déborder.

Mais au delà de ça, la réflexivité permet quand même de faire des chose qu'on ne pourrait pas aborder de manière aussi souple sans.
Imaginons une appli type server qui ne doit pas s’interrompre, mais dont on aimerait changer le comportement.
Une solution serait d'avoir une inputbox qui demanderait d'entrer une ligne de code.
Ainsi on pourrait modifier a chaud des globales, appeler des fonction ou juste récupérer des infos.
Sans ça, il faudrait prévoir et parser la chaine pour tout les cas imaginable, et on en oublierait surement.
Signez ici

lesolutionneur
Niveau 7
Niveau 7
Messages : 368
Enregistré le : ven. 09 déc. 2011 11:25
Status : Hors ligne

Re: [Tuto] Réflexion en Autoit

#7

Message par lesolutionneur » mar. 03 janv. 2012 22:35

Perso, je trouve qu'exécuter du code qui varie au milieu d'un programme est une usine à gaz (clin d'oeil aux programmeurs asm qui se sont essayé au SMC ("self modifying code"))

Mais après, tu as raison, cela peut-être utile, je pense aux programmes légers, tu peux au démarrage télècharger le code à exécuter et si le type est pas connecté sur Internet, ça prend la version en cache, comme ça, pas de système de mise à jour, tout est fait en "live".

Avatar du membre
Iste
Modérateur
Modérateur
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [Tuto] Réflexion en Autoit

#8

Message par Iste » mar. 03 janv. 2012 22:43

Oui comme dit, il est tres facile de faire un code horrible avec cela.
C'est pour cela que si on est pas certain de devoir l'utiliser, il vaut mieux s'en passer !

Toute foi, ca serait dommage quand même de ne pas avoir cet outil sous la main, qui bien maitrisé peut faire des merveilles !

Je me souvient d'un projet en java ou on avait un fichier xml qui faisait le lien entre les table de la bdd et les dto, on pouvait ajouter des tables dans la base puis simplement créer la class qui va avec, sans devoir toucher au reste du code !
Signez ici

Avatar du membre
Jerome
Modérateur
Modérateur
Messages : 661
Enregistré le : mar. 07 avr. 2009 07:35
Localisation : Picardie
Status : Hors ligne

Re: [Tuto] Réflexion en Autoit

#9

Message par Jerome » mar. 03 janv. 2012 22:46

Coucou,


This is sympathique,


Merci pour le Tuto Iste.


Personnellement, je n'ai jamais eu l'utilité de telles fonctions.


Malgré cela, il est toujours bon de les connaitre et de les garder dans un coin :)




Jérôme

Répondre