Page 1 sur 1
[R] Eviter les if-else/switchcase a ralonge avec un tableau
Posté : jeu. 06 nov. 2014 17:23
par Faco
Bonjour à tous,
Le principale est dans le titre.
je fais un script qui s'apparente à un tchat TCP/IP est je l'enrichie de fonctions petit à petit.
Ces fonctions je les ai rangé dans un bon gros IF/ELSE qui n'est fini pas de prendre des lignes

.
Code : Tout sélectionner
....
ElseIf $Data = "#IP#" Then
....
ElseIf $Data = "#CLOSECLIENT#" Then
....
ElseIf $Data = "#INFO#" Then
...
Je crois me souvenir avoir fait un truc dans le genre en J2EE il y a quelques années où on avais mis en place un tableau (array, pas un dessin

) avec la commande que l'on recevais (ex ici #IP#) et la fonction à appeler.
C'est loin, flou et confus dans ma mémoire, j'ai besoin d'aide.
Dites moi si c'est pas claire.
Merci

Re: [..]Eviter les if-else/switch-case a ralonge avec un tab
Posté : jeu. 06 nov. 2014 17:34
par mikell
C'est pas clair
Je blague
Eventuellement comme ça
Code : Tout sélectionner
Local $array[$n][2] ; col0 = commande, col1 = fonction
For $i = 0 to $n-1
If $Data = $array[$i][0] Then Call($array[$i][1])
Next
Mais je vois pas bien l'avantage par rapport à un Switch/Case standard
Re: [..] Eviter les if-else/switchcase a ralonge avec un tab
Posté : ven. 07 nov. 2014 00:45
par orax
Le nom de la commande est envoyé à _exec, qui se charge d'exécuter la fonction correspondante (la fonction étant préfixée avec "__cmd_" par exemple). Par contre ce n'est pas avec un tableau comme tu voulais.
► Afficher le texte
Code : Tout sélectionner
$r = _exec('test')
ConsoleWrite($r & @CRLF)
$r = _exec('gnagnagna')
ConsoleWrite(Hex(@error) & @CRLF)
Func __cmd_test()
ConsoleWrite('commande test' & @CRLF)
Return 'mmmmh'
EndFunc
Func _exec($cmd)
If StringRegExp($cmd, '[a-zA-Z0-9_]') Then
$r=Call('__cmd_' & $cmd)
Return SetError(@error, @extended, $r)
Else
Return SetError(1)
EndIf
EndFunc
Édité > Avec la βετα et Map. Ce qui ressemble plus à un tableau d'ailleurs.
► Afficher le texte
Code : Tout sélectionner
Local $mMap[]
$mMap["#IP#"] = _cmd_IP
$r = _exec("#IP#")
ConsoleWrite($r & @CRLF)
_exec("#???#")
If @error Then ConsoleWrite("La commande n'existe pas." & @CRLF)
Func _cmd_IP()
ConsoleWrite('#IP#' & @CRLF)
Return 'coucou'
EndFunc ;==>_cmd_IP
Func _exec($cmd)
$r = Call($mMap[$cmd])
Return SetError(@error, @extended, $r)
EndFunc ;==>_exec
Re: [..] Eviter les if-else/switchcase a ralonge avec un tab
Posté : ven. 07 nov. 2014 15:44
par Faco
et ba voila, ça fait déjà bien deux ans que je fais de l'autoit et j' étais pas encore tombé sur la fonction 'Call'. De même, je ne pensais pas pouvoir indicer un tableau avec un chaine de caractère.
Merci a vous deux.
Je pousse un peu plus, si vous savez pas ou que c'est pas possible je passerai quand même le post en résolut.
Re exemple avec mon #IP# :
Mon serveur broadcast à tous le monde qu'il veut leur ip et tous le monde répond "#MYIP#192.168......."
est ce qu'il y aurais un truc facile de genre :
..................................................................................................
En fait je viens de trouver une solution, je l'a dit histoire d'avoir des commentaires si y a plus simple.
Je vais donner une taille de caractères fixe à mes fonction (ex 8 ) et un séparateur ( ex "/|\" ) et faire un truc du genre :
► Afficher le texte
Code : Tout sélectionner
Local $mMap[]
$mMap["#IP1234#"] = _cmd_IP
$mMap["#MYIP12#"] = _cmd_MYIP
.....
$cmd = "commandeParm1/|\Param2/|\Param3"
$commande = StringLeft($cmd, 8)
if StringLen($cmd)<>8 Then
$arrayParam = StringSplit(StringTrimLeft($cmd, 8),"/|\")
Switch $arrayParam[0]
case 1
Call($mMap[$commande],$arrayParam[1])
case 2
Call($mMap[$commande],$arrayParam[1],$arrayParam[2])
case 3
Call($mMap[$commande],$arrayParam[1],$arrayParam[2],$arrayParam[3])
Case .....
.....
EndSwitch
Else
$r = Call($mMap[$commande])
EndIf
C'est pas aboutit mais c'est l'idée, alors?
Encore merci à vous

Re: [..] Eviter les if-else/switchcase a ralonge avec un tab
Posté : ven. 07 nov. 2014 17:12
par Faco
Et question supplémentaire qui ne m’intéresse pas pour le code présent mais mas culture personnel.
On peut faire, comme en C++, plusieurs fois la même fonction avec un nombre de paramètres différent. le programme choisissant la bonne fonction en fonction du nombres de param?
Re: [..] Eviter les if-else/switchcase a ralonge avec un tab
Posté : sam. 08 nov. 2014 00:54
par orax
L'avantage de Call() est qu'il accepte les arguments sous forme d'un array. Donc pas besoin d'utiliser un Switch comme tu l'as fait. Les arguments sont stockés dans $arrayParam et Call() se débrouille avec.
► Afficher le texte
Code : Tout sélectionner
#include <Array.au3>
Local $mMap[]
$mMap["#IP#"] = _cmd_IP
$mMap["#MYIP#"] = _cmd_MYIP
$mMap["#MYIP2#"] = _cmd_MYIP2
$r = _exec("#IP#/|\Parm1/|\Param2/|\Param3")
ConsoleWrite(@error & @CRLF)
ConsoleWrite($r & @CRLF)
$r = _exec("#MYIP#")
$r = _exec("#MYIP2#/|\Parm1")
Func _cmd_IP($a, $b, $c)
ConsoleWrite('#IP#' & @CRLF)
ConsoleWrite($a & @CRLF)
ConsoleWrite($b & @CRLF)
ConsoleWrite($c & @CRLF)
Return '_cmd_IP'
EndFunc ;==>_cmd_IP
Func _cmd_MYIP()
ConsoleWrite('#MYIP#' & @CRLF)
EndFunc ;==>_cmd_MYIP
Func _cmd_MYIP2($a)
ConsoleWrite('#MYIP2#' & @CRLF)
ConsoleWrite($a & @CRLF)
EndFunc ;==>_cmd_MYIP2
Func _exec($cmd)
Local $commande = ""
$arrayParam = StringSplit($cmd, "/|\", $STR_ENTIRESPLIT + $STR_NOCOUNT) ; $STR_ENTIRESPLIT est nécessaire puisque il y a plusieurs caractères dans /|\
$commande = $arrayParam[0]
; s'il y a une commande + au moins 1 paramètre (le premier paramètre se trouvera en arrayParam[1])
If UBound($arrayParam) > 1 Then
$arrayParam[0] = "CallArgArray" ; (depuis la doc) This is required, otherwise, Call() will not recognize the array as containing arguments
$r = Call($mMap[$commande], $arrayParam)
Else
$r = Call($mMap[$commande])
EndIf
Return SetError(@error, @extended, $r)
EndFunc ;==>_exec
Pour la question, à ma connaissance non, on ne peut pas faire de surcharge de fonctions comme en C++.
Édité > On ne peut pas créer deux fonctions test() et test($a, $b) qui auront chacune un comportement différent mais on peut le simuler. Le code ci-dessous montre des appels de _a() avec différents paramètres. En fonction du nombre de paramètres et/ou de leur type, la fonction peut réagir différemment.
► Afficher le texte
Code : Tout sélectionner
_a() ; _a()
_a(1) ; _a(Int32)
_a('a') ; _a(P1)
_a('a', 'a') ; _a(P1, P2)
_a('a', 'a', 'a') ; _a(P1, P2, P3)
_a(1, True, 'a') ; _a(Int32, Bool, P3)
Func _a($a = '', $b = '', $c = '')
If @NumParams = 0 Then
ConsoleWrite('_a()' & @CRLF)
ElseIf @NumParams = 1 Then
If VarGetType($a) = 'Int32' Then
ConsoleWrite('_a(Int32)' & @CRLF)
Else
ConsoleWrite('_a(P1)' & @CRLF)
EndIf
ElseIf @NumParams = 2 Then
ConsoleWrite('_a(P1, P2)' & @CRLF)
ElseIf @NumParams = 3 Then
If VarGetType($a) = 'Int32' And VarGetType($b) = 'Bool' Then
ConsoleWrite('_a(Int32, Bool, P3)' & @CRLF)
Else
ConsoleWrite('_a(P1, P2, P3)' & @CRLF)
EndIf
EndIf
EndFunc ;==>_a
Re: [R] Eviter les if-else/switchcase a ralonge avec un tabl
Posté : sam. 08 nov. 2014 17:13
par Faco
Merci merci
