Apprendre Tcl en écrivant un jeu simple


  • Français


  • Mon chemin vers Tcl a commencé avec un besoin récent d’automatiser un utilitaire de configuration de ligne de commande basé sur Java. Je fais un peu de programmation d’automatisation à l’aide d’Ansible, et j’utilise occasionnellement le module expect. Franchement, je trouve que ce module a une utilité limitée pour un certain nombre de raisons, notamment : la difficulté à séquencer des invites identiques, à capturer des valeurs à utiliser dans des étapes supplémentaires, une flexibilité limitée avec la logique de contrôle, etc. Parfois, vous pouvez vous en sortir en utilisant le module shell à la place. Mais parfois, vous rencontrez cette interface de ligne de commande mal conduite et trop compliquée qui semble impossible à automatiser.

    Dans mon cas, j’automatisais l’installation d’un des programmes de mon entreprise. La dernière étape de configuration ne pouvait être effectuée que via la ligne de commande, via plusieurs invites répétitives mal formées et une sortie de données nécessitant une capture. Le bon vieux Expect traditionnel était la seule réponse. Une compréhension approfondie de Tcl n’est pas nécessaire pour utiliser les bases d’Expect, mais plus vous en savez, plus vous pouvez en tirer de puissance. Ceci est un sujet pour un article de suivi. Pour l’instant, j’explore les constructions de langage de base de Tcl, qui incluent l’entrée utilisateur, la sortie, les variables, l’évaluation conditionnelle, les boucles et les fonctions simples.

    Installer TCL

    Sur un système Linux, j’utilise ceci:

    # dnf install tcl
    # which tclsh
    /bin/tclsh

    Sur macOS, vous pouvez utiliser Homebrew pour installer la dernière Tcl :

    $ brew install tcl-tk
    $ which tclsh
    /usr/local/bin/tclsh

    Devinez le nombre en Tcl

    Commencez par créer le script exécutable de base numgame.tcl:

    $ touch numgame.tcl
    $ chmod 755 numgame.tcl

    Et puis commencez à coder dans votre fichier dirigé par l’en-tête de script shebang habituel :

    #!/usr/bin/tclsh

    Voici quelques mots rapides sur les artefacts de Tcl à suivre avec cet article.

    Le premier point est que tout Tcl est considéré comme une série de chaînes. Les variables sont généralement traitées comme des chaînes, mais peuvent changer automatiquement de type et de représentation interne (ce que vous n’avez généralement aucune visibilité). Les fonctions peuvent interpréter leurs arguments de chaîne comme des nombres ( expr) et ne sont transmis que par valeur. Les chaînes sont généralement délimitées par des guillemets doubles ou des accolades. Les guillemets permettent une extension variable et des séquences d’échappement, et les accolades n’imposent aucune extension.

    Le point suivant est que les instructions Tcl peuvent être séparées par des points-virgules mais ne le sont généralement pas. Les lignes d’instruction peuvent être divisées à l’aide du caractère barre oblique inverse. Cependant, il est courant de placer des instructions multilignes entre accolades pour éviter d’avoir besoin de cela. Les accolades sont simplement plus simples, et le formatage du code ci-dessous reflète cela. Les accolades permettent une évaluation différée des chaînes. Une valeur est passée à une fonction avant que Tcl n’effectue la substitution de variable.

    Enfin, Tcl utilise des crochets pour la substitution de commande. Tout ce qui se trouve entre crochets est envoyé à une nouvelle invocation récursive de l’interpréteur Tcl pour évaluation. C’est pratique pour appeler des fonctions au milieu d’expressions ou pour générer des paramètres pour des fonctions.

    Procédures

    Bien que cela ne soit pas nécessaire pour ce jeu, je commence par un exemple de définition d’une fonction en Tcl que vous pourrez utiliser plus tard :

    proc used_time {start} {
    	return [expr [clock seconds] - $start]
    }

    En utilisant proc définit ceci comme une définition de fonction (ou de procédure). Vient ensuite le nom de la fonction. Ceci est ensuite suivi d’une liste contenant les paramètres ; dans ce cas 1 paramètre {start} puis suivi du corps de la fonction. Notez que l’accolade du corps commence sur cette ligne, elle ne peut pas être sur la ligne suivante. La fonction renvoie une valeur. La valeur renvoyée est une évaluation composée (accolades) qui commence par lire l’horloge système [clock seconds] et fait le calcul pour soustraire le $start paramètre.

    Configuration, logique et finition

    Vous pouvez ajouter plus de détails au reste de ce jeu avec une configuration initiale, itérer sur les suppositions du joueur, puis imprimer les résultats une fois terminé :

    set num [expr round(rand()*100)]
    set starttime [clock seconds]
    set guess -1
    set count 0
    
    puts "Guess a number between 1 and 100"
    
    while { $guess != $num } {
    	incr count
    	puts -nonewline "==> "
    	flush stdout
    	gets stdin guess
    
    	if { $guess < $num } {
    		puts "Too small, try again"
    	} elseif { $guess > $num } {
    		puts "Too large, try again"
    	} else {
    		puts "That's right!"
    	}
    }
    
    set used [used_time $starttime]
    
    puts "You guessed value $num after $count tries and $used elapsed seconds"
    

    Programmation et développement

    La première set les instructions établissent des variables. Les deux premières évaluent les expressions pour discerner un nombre aléatoire entre 1 et 100, et la suivante enregistre l’heure de début de l’horloge système.

    Le puts et gets sont utilisées pour la sortie vers et l’entrée du lecteur. Le puts J’ai utilisé implicitement la sortie standard pour la sortie. Le gets a besoin que le canal d’entrée soit défini, donc ce code spécifie stdin comme source pour l’entrée du terminal de l’utilisateur.

    Le flush stdout commande est nécessaire lorsque puts omet la terminaison de fin de ligne car Tcl met en mémoire tampon la sortie et il se peut qu’elle ne s’affiche pas avant que la prochaine E/S ne soit nécessaire.

    De là le while L’instruction illustre la structure de contrôle en boucle et la logique conditionnelle nécessaires pour donner un retour au joueur et éventuellement terminer la boucle.

    Le final set La commande appelle notre fonction pour calculer les secondes écoulées pour le jeu, suivies des statistiques collectées pour terminer la partie.

    Joue-le!

    $ ./numgame.tcl
    Guess a number between 1 and 100
    ==> 100
    Too large, try again
    ==> 50
    Too large, try again
    ==> 25
    Too large, try again
    ==> 12
    Too large, try again
    ==> 6
    Too large, try again
    ==> 3
    That's right!
    You guessed value 3 after 6 tries and 20 elapsed seconds
    

    Continuer à apprendre

    Lorsque j’ai commencé cet exercice, je doutais de l’utilité de revenir à un langage à la mode de la fin des années 1990. En cours de route, j’ai trouvé quelques éléments sur Tcl que j’ai vraiment appréciés – mon préféré étant l’évaluation de la commande entre crochets. Cela semble tellement plus facile à lire et à utiliser que de nombreux autres langages qui abusent des structures de fermeture compliquées. Ce que je pensais être une langue morte était en fait toujours florissant et pris en charge sur plusieurs plates-formes. J’ai appris quelques nouvelles compétences et développé une appréciation pour cette langue vénérable.

    Consultez le site officiel sur https://www.tcl-lang.org. Vous pouvez trouver des références à la dernière source, aux distributions binaires, aux forums, à la documentation et aux informations sur les conférences qui sont toujours en cours.

    Source

    Houssen Moshinaly

    Pour contacter personnellement le taulier :

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

    Copy code