Guide de style pour Tcl

 

Traduction (en cours) de http://wiki.tcl.tk/708

Tcl - guide de style (ou : Règles d'écriture)

Le style de codage (d'encodage) fait souvent l'objet de débats passionnés, d'une ferveur quasi religieuse. Mais l'essentiel est qu'un code cohérent, se conformant à un style raisonnablement réfléchi, produira un code plus lisible, plus facile a maintenir et sans faute, plutôt qu'une manière arbitraire et improvisée de programmer. A cet égard, Tcl n'est pas différent. Le code de toute application et / ou bibliothèque en Tcl, peut bénéficier de suivre de simples directives qui rendront le code plus lisible et plus fiable. Une documentation commode est déjà disponible sous la forme du Tcl Style Guide de Ray Johnson, guide qui est disponible à : http://www.tcl.tk/doc/styleGuide.pdf

Ce document décrit des conventions de haut niveau pour écrire des scripts comme les conventions de nommage et l'organisation des fichiers.


Plan du document :

 1 Introduction

 2 Fichiers exécutables

 3 Paquets et espaces de noms (ou : espaces de nommage)
   3.1 Noms des paquets
   3.2 Numéros de version
   3.3 Espaces des noms des paquets
   3.4 Structure

 4 Comment organiser un fichier de code
   4.1 Les en-tête de fichiers
   4.2 Les paquets multi fichiers
   4.3 Les en-tête de procédures
   4.4 Les déclarations de procédures
   4.5 L'ordre des paramètres
   4.6 Les corps des procédures

 5 Les conventions de nommage
   5.1 Considérations générales
   5.2 Règles de syntaxe élémentaire

 6 Conventions de codage de bas niveau
   6.1 Les indentations sont de 4 espaces
   6.2 Les commentaires de code occupent des lignes entières
   6.3 L'indentation des suites de ligne est de 8 espaces
   6.4 Seulement une commande par ligne
   6.5 Les accolades : { vont a la fin d'une ligne
   6.6 Mettre les expressions entre parenthèses
   6.7 Utiliser toujours la commande "return"
   6.8 La commande "switch"
   6.9 La commande "if"

 7 Documenter le code
   7.1 Documenter les choses qui ont un effet important
   7.2 Ne répétez pas simplement ce que contient le code
   7.3 Documentez chaque chose en un seul et unique endroit
   7.4 Écrivez du code propre
   7.5 Documentez au fur et a mesure du codage
   7.6 Documentez les situations délicates

 8 Tester
   8.1 Fondamentaux
   8.2 Organisation des tests
   8.3 Étendue des tests
   8.4 Correction des erreurs
   8.5 Caractéristiques délicates
   8.6 Indépendance des tests

 9 Divers
   9.1 Questions liées à la portabilité
   9.2 Fichier enregistrant le suivi des modifications

Section 1 Introduction

Ceci est un manuel pour ceux qui développent en Tcl soit avec Wish soit avec toute application de Tcl. Il décrit un ensemble de conventions pour écrire du code et les scripts correspondants. En premier lieu, les conventions garantissent que certaines choses importantes soient faites ; par exemple, chaque procédure doit disposer d'une documentation qui décrit chacun de ses arguments ainsi que son résultat, il faut également qu'il existe des scripts de tests qui vont tester chaque ligne de code. En second lieu, ces conventions garantissent que tout le code de Tcl et de Tk procédera d'un style uniforme. Ceci nous facilite, aux uns et aux autres, l'utilisation, la lecture et la maintenance du code. Troisièmement, les conventions nous aident à éviter les erreurs les plus courantes en nous empêchant d'utiliser des constructions sujettes à l'erreur, comme construire des listes manuellement plutôt que d'utiliser les procédures de construction de listes.

Ce document s'appuie fortement sur le Tcl/Tk Engineering Manual [1] ("Manuel d’ingénierie de Tcl/Tk") écrit par John Ousterhout. Le manuel d’ingénierie de John précisait le style utilisé en langage C pour l'implantation de Tcl/Tk et de nombre de ses extensions. Ce manuel est très précieux pour le développement de Tcl/Tk et est une raison importante qui explique pourquoi Tcl est un système assez facile a maintenir. L’établissement de tout standard de style implique des compromis qui sont généralement subjectifs. Ce standard a été établi a l'aide d'un processus itératif impliquant le groupe Tcl/Tk de "Sun laboratories". Je ne prétends pas que ces conventions soient les meilleures possibles, mais l'exactitude des conventions ne fait pas une telle différence. La chose la plus importante c'est que nous procédions tous de la même manière.

S'il vous plaît, écrivez votre code afin qu'il se conforme aux conventions, d'entrée de jeu. Par exemple, n'écrivez pas du code sans y inclure les commentaires en supposant que vous y reviendrez et ferez les commentaires plus tard lorsque le code fonctionnera. Ceci ne se produira tout simplement pas. Malgré vos bonnes résolutions, quand viendra le moment de revenir en arrière et d'écrire les commentaires, vous découvrirez que vous avez une douzaine de choses plus importantes à faire ; au fur et à mesure que le corps de code non commenté croit, il vous sera de plus en plus difficile de trouver l'énergie nécessaire pour faire machine arrière et régler tout cela. Une des règles fondamentales des logiciels est que leur structure ne peut que se dégrader dans le temps ; si vous ne le construisez pas correctement dès l'origine, il ne le deviendra jamais plus tard.

Le reste de ce document comprend 8 parties principales. Nous commencerons avec la Section 2 qui traite des fichiers exécutables. La Section 3 traite de l'ensemble de la structure des paquets et des espaces de noms. La Section 4 décrit la structure d'un fichier de code Tcl et la manière d'écrire des en-tête de procédures. La Section 5 décrit les conventions de nommage en Tcl. La Section 6 présente les conventions de codage de bas niveau, comme comment indenter et ou utiliser les accolades. La Section 7 contient un ensemble de règles et de suggestions pour écrire des commentaires. La Section 8 décrit comment écrire et maintenir des ensembles de tests. La Section 9 contient quelques sujets divers, tels que la mise en œuvre d'un journal des modifications.

SECTION 2 Fichiers exécutables

Un "exécutable" est un fichier, ou une collection de fichiers, ou toute autre collection de code Tcl accompagné de l'environnement d’exécution nécessaire. Souvent désigné comme une application un exécutable est simplement ce que vous exécutez pour démarrer votre programme. Le format et l'exacte construction d'un exécutable sont spécifiques à chaque plate-forme. A un certain point, toutefois, un script Tcl de démarrage sera évalué. C est le script de démarrage qui va démarrer toute application basée sur Tcl.

Le rôle du script de démarrage est de charger tous les paquets nécessaires, mettre en place tout état particulier non lié à des paquets et enfin, démarrer l'application en faisant appel a des routines contenues dans un paquet de Tcl. Si le script de démarrage dépasse quelques lignes, il devrait probablement être lui même un paquet.

Il existe plusieurs façons de créer des scripts exécutables. Chaque plate-forme importante a, en général, une façon unique de créer une application exécutable. Voici une courte description de comment ce type d'application doit être créé sur chaque plate-forme.

1 La méthode la plus courante pour créer des applications exécutables sur les plates-formes UNIX est l'utilisation de l’infâme "!#" (appelé couramment "un shebang") mécanisme faisant partie de la plupart des interpréteurs de commandes. Malheureusement, la démarche la plus courante consistant à indiquer simplement un chemin à Wish n'est pas recommandée.

Ne faites pas :

 #!/usr/local/tclsh8.0 -f "$0" "$@"

Cette méthode ne marchera pas si le fichier tclsh est un autre script qui, par exemple, situe et démarre la plus récente version de Tcl. Cela implique également que tclsh soit à un emplacement particulier, ce qui diminue la portabilité du script. A la place, il faut utiliser la méthode ci-après qui appelle /bin/sh qui, à son tour "exec" l'application de Wish

 #!/bin/sh
 # the next line restarts using wish \
 exec wish8.0 "$0" "$@"

Cet exemple localisera l'application Wish dans le chemin de l'utilisateur, ce qui peut être très utile pour les développeurs. L'oblique inversée ( \ ) est reconnue par sh comme un élément de commentaire, mais en Tcl l'oblique inversée poursuit le commentaire sur la ligne suivante ce qui empêche la commande exec de s'exécuter à nouveau. Cependant, des scripts plus stables nécessiteraient probablement que soit inclus le chemin absolu plutôt que simplement Wish. Notez que le numéro de version de tclsh ou de l’interpréteur de Wish est généralement ajouté a la fin du nom du programme. Ceci vous permet d'utiliser une version spécifique de Tcl. De plus, de nombreux sites comprennent un lien de Wish vers la dernière version installée. Ceci est utile si vous savez que votre code fonctionnera avec toute version de Tcl.

Une autre méthode rencontrée couramment est :

 #!/usr/bin/env tclsh

Si vous avez besoin de Tk il vous suffira alors de faire un "package require Tk". Vous pourriez envisager d'utiliser le script ci dessus et vous pourriez alors rencontrer des difficultés si vous disposiez de plusieurs installations de Tcl/Tk

2. Sous Windows il vous suffit d'utiliser l'extension " .tcl " à la fin du nom du fichier, qui sera exécuté quand l'utilisateur le double cliquera. Ceci implique, bien évidemment que vous ayez installé Tcl/Tk au préalable. Sinon, vous pouvez aussi créer un fichier ".bat" qui va exécuter tclsh ou Wish en fournissant le chemin absolu du script de démarrage. Veuillez consulter la documentation de Windows pour plus de détails au sujet des fichiers ".bat"

3. La plate-forme Macintosh, avant MacOS X, n'avait pas vraiment la notion de fichier de Tcl exécutable. La raison en était que, contrairement a UNIX ou Windows, on ne pouvait exécuter qu'une seule instance d'une application à la fois. De telle sorte qu'au lieu de lancer Wish avec un script spécifique à charger, vous deviez créer une copie de l'application de Wish qui était attachée à votre script.

La façon la plus simple pour le faire était d'employer le greffon Tcl de l'application Drag&Drop ou le constructeur d'interfaces graphiques SpecTcl qui pouvaient faire ce travail pour vous. Vous pouviez également le faire à la main en plaçant le script de démarrage dans une ressource TEXT appelée "tclshrc" - ceci garantissant son chargement au démarrage. Ce qui pouvait être fait avec ResEdit (un outil mis a disposition par Apple) ou d'autres outils capables de manipuler des ressources. Des scripts supplémentaires peuvent également être placés dans une ressource TEXT afin que l'application complète y soit contenue.

Cependant, le support de Tcl pour le Macintosh a évolué et actuellement supporte seulement Mac OS X. Ainsi les explications ci-dessus ne concernent que des versions de Tcl plus anciennes

SECTION 3 Paquets et espaces des noms

Les applications de Tcl consistent en un ensemble de paquets. Chaque paquet procure du code qui implante un ensemble de caractéristiques liées. Par exemple, Tcl lui même est un paquet, comme l'est Tk, il se trouve que ces paquets sont implantés aussi bien en C qu'en Tcl. D'autres paquets sont complètement écrits en Tcl tel que le paquet "http" inclus dans la distribution Tcl. Les paquets sont les unités au sein desquels le code est développé et distribué; un paquet unique est typiquement développé par une personne unique ou un groupe unique et distribué comme une unité. Il est possible de combiner de nombreux paquets développés indépendamment les uns des autres en une unique application; c est avec cette possibilité en tête que les paquets doivent être conçus. La notion d'espace des noms a été créée pour faciliter cela. Les espaces de noms permettent de cacher les aspects privés des paquets et permettent d'éviter les collisions de noms. Un paquet exportera généralement un espace de noms public qui inclura tous les états et routines qui sont associés avec ce paquet. Un paquet ne doit comprendre ni variables globales ni procédures globales. Il faut éviter, lors du chargement d'un paquet, les effets de bord. Ce document mettra l'accent sur les paquets écrits entièrement en Tcl. Pour une discussion concernant les paquets écrits en C ou en C et Tcl reportez vous au "Tcl/tk Engineering Manual".

SECTION 3.1 Noms des paquets'

Chaque paquet doit avoir un nom unique. Le nom des paquets sert à leur identification. Ce nom est également celui de l'espace de noms que le paquet exporte. Le mieux est d'avoir un nom simple, d'un mot, tout en minuscules comme "http". Des noms composés de plusieurs mots sont également corrects. Les mots supplémentaires doivent simplement être rattachés au premier mot mais doivent commencer par une majuscule comme "specMenu".

Le fait d'utiliser un nom unique pour votre paquet exige un composant collaboratif. Pour des projets internes ceci est une tache facile et peut, en général être décidé par la direction ou les principaux ingénieurs de votre organisation. Pour des paquets que vous souhaitez publier, vous devriez faire un effort pour vous assurer qu'un paquet existant n'utilise pas déjà ce même nom. Souvent, ceci peut être fait en vérifiant sur le forum "comp.lang.tcl" (aussi fr.comp.lang.tcl ) ou sur les sites ftp de Tcl les plus courants. Il est également suggéré, mais ce n'est pas impératif, que vous inscriviez votre nom sur "NIST Identifier Collaboration Service (NICS)" qui se trouve a : http://pitch.nist.gov/nics.

SECTION 3.2 Numération des versions

Chaque paquet a un numéro de version en deux parties tel que 7.4. Le premier nombre (7) est appelé le numéro majeur de la version et le second (4 ) le numéro mineur. Le numéro de version change à chaque nouvelle version publique du paquet. Si la nouvelle version contient seulement des corrections de bogues, de nouvelles fonctionnalités, et d'autres modifications à compatibilité ascendante, de telle sorte que le code et les scripts qui fonctionnaient correctement avec l'ancienne version puissent le faire avec la nouvelle version, alors le numéro mineur de la version s'incrémente et le numéro majeur reste inchangé (ex : de 7.4 à 7.5). Si la nouvelle version contient des incompatibilités conséquentes, de telle sorte que le code et les scripts existants devront subir des modifications pour s'exécuter avec la nouvelle version, alors c est le numéro majeur qui va être incrémenté et le numéro mineur sera remis à zéro ( ex: de 7.4 à 8.0).

SECTION 3.3 Espace des noms des paquets

A partir de sa version 8.0, Tcl accepte les espaces de noms pour cacher la structure interne du paquet. Ceci permet d'éviter la collision des noms et procure une façon plus simple de gérer les paquets. Tous les paquets écrits pour Tcl 8.0 et au delà devraient utiliser des espaces de noms. Le nom de l'espace de nom devrait être le même que celui du paquet.

SECTION 3.4 Structure

Il existe plusieurs façons de déployer un paquet de commandes Tcl. Un fichier "pkgindex.tcl" est utilisé pour créer des paquets qui peuvent être chargés a volonté par tout script en Tcl. Comme le fait un fichier "tclindex" un paquet spécifie un ensemble de bibliothèques et/ou de bibliothèques partagées qui peuvent être chargées en tant que de besoin. Cependant, un paquet doit être explicitement invoqué en utilisant la commande "package require". Vous pouvez utiliser la commande "pkg_mkindex" afin de créer, pour votre usage, un fichier d'index du paquet, Dans la plupart des cas, et plus particulièrement dans le code que vous distribuez il vaut mieux utiliser un paquet plutôt que le mécanisme d'auto_chargement de "tclindex".

 # specMenu.tcl
 #
 # Résumé
 # Ce fichier implémente le code de Tcl pour créer et administrer les menus de l'application SpecTcl.
 #
 # Copyright (c) 1994-1997 Sun Microsystems, Inc.
 #
 # Copyright
 # Voir le fichier "license.terms" pour tous renseignements concernant l'usage et la redistribution de ce fichier, et pour l' AVIS DE NON RESPONSABILITÉ
 #
 # Chaine de révision
 # SCCS: %Z% %M% %I% %E% %U%
 #
 # Definition du paquet
 package require specTable
 package provide specMenu 1.0

 namespace eval specMenu {
     namespace export addMenu
     array set menuData {one two three}
     ...
 }

Figure 1. Un exemple de page d'en-tête

Sur la plate-forme Macintosh, les bibliothèques partagées peuvent être créées sous la forme de paquet auto-contenus. Il vous suffit d'ajouter une ressource TEXT avec pour nom "pkgindex", qui sera traitée exactement de la même manière qu'un fichier "pkgindex.tcl". La ressource "pkgIndex" devrait avoir le même format que le fichier "pkgIndex.tcl".

SECTION 4 Comment organiser un fichier de code

Chaque fichier de code source devrait contenir une application complète ou un ensemble de procédures apparentées qui constituent un paquet ou tout autre type de module identifiable, tel que l'implémentation des menus de votre application, ou un ensemble de procédures implémentant un accès HTTP. Avant de passer à l'écriture du code vous devriez réfléchir soigneusement quant aux fonctions qu'il faut procurer puis à leur répartition logique dans des fichiers. La taille de fichiers généralement la plus gérable se situe dans la gamme des 500-2000 lignes. Si un fichier dépasse largement cette taille, il vous sera difficile de vous souvenir de tout ce que fait ce fichier. Si un fichier est significativement plus court alors vous risquez de vous retrouver avec beaucoup trop de fichier dans un répertoire ce qui est aussi difficile à gérer.

SECTION 4.1 L'en-tête de fichier

On appelle "en-tête" la première partie d'un fichier de code. Elle contient des informations générales qui sont pertinentes pour l'ensemble du fichier. Il s'agit de tout sauf des définitions des procédures contenues dans le fichier. L'en-tête se compose, typiquement, de quatre parties, comme le montre la Figure 1:

Résumé. Les quelques premières lignes donnent le nom du fichier et une brève description d'ensemble des fonctions qui sont mises à disposition par le fichier, exactement de la même manière que dans les en-tête de fichiers.

Notice relative aux droits d'Auteurs. Cette notice protège la propriété du fichier. Ici, le droit d'Auteur est inclus dans les sources de Tcl/Tk. Des paquets contenant des éléments plus particuliers comporteraient plutôt la mention "Tous droits Réservés". Si plus d'une entité avait participé alors chacune devrait avoir une ligne de droits d'Auteur séparée.

Chaîne de Révision. Les contenus de cette chaîne sont administrés automatiquement par le système de contrôle de code source pour chaque fichier, tels que RCS ou SCCS (SCCS est employé dans l'exemple de la Figure 1). Elle identifie la dernière révision du fichier, date de la dernière modification, et ainsi de suite.

Définition de paquet: Toutes commandes "require" concernant des paquets, dont ce paquet dépend, doivent être les premières lignes de code dans le fichier. Toute variable globale que ce fichier utilise doit être déclarée en haut de la page. A la suite, il faut trouver la définition de l'espace de noms et la liste d'exportation doit être le premier item dans la définition de l'espace de noms. Veuillez structurer les pages d'en-tête dans l'ordre exact indiqué ci dessus et respectez la syntaxe de la Figure 1 aussi exactement que possible. le fichier "fileHead.tcl " procure un patron de page d'en-tête.

SECTION 4.2 Paquets multi-fichiers

Certains paquets peuvent être trop grands pour tenir dans un seul fichier. Il vous est possible d'envisager de diviser ce paquet en plusieurs paquets indépendants. Cependant si cette hypothèse n'est pas retenue il faut que vous fassiez d'un des fichiers le fichier primaire. Ce fichier primaire comprendra la totalité de la liste d'exportation ainsi que les définitions de toutes les variables et procédures exportées. Les fichiers secondaires contiendront seulement les routines de support du fichier primaire. Il est important que vous construisiez votre paquet de cette manière car, sinon, les utilitaires comme "pkg_mkIndex" ne fonctionneront pas correctement. Enfin, les en-tête des différents fichiers doivent expliciter quel fichier est le fichier primaire et lesquels sont les fichiers de support.

SECTION 4.3 en-tête des procédures

Après les en-tête vous trouverez une ou plusieurs procédures. Chaque procédure commence par une en-tête de procédure qui fournit une documentation générale de la procédure, suivie par la déclaration et le corps de la procédure. Voir la Figure 2 pour un exemple. L’en-tête doit contenir tout ce qu'un appelant de la procédure doit en connaître afin de pouvoir l'utiliser, et rien d'autre. Cela se décompose en trois parties :

Résumé : Les premières lignes dans l’en-tête donnent le nom de la procédure, suivi par une brève description de ce que fait la procédure. Il ne peut s'agir d'une description détaillée de la façon dont la procédure est implémentée, mais plutôt un résumé de haut niveau de sa fonction. Dans certains cas, comme par exemple les procédures de rappel, je recommande de décrire les conditions d'invocation de la procédure et qui l'invoquera.

Arguments : Cette partie de l'en-tété décrit les arguments que la procédure attend. Une ligne, au moins, par argument. Le commentaire doit décrire le type attendu et doit décrire sa fonction. Les arguments optionnels doivent être signalés et le comportement par défaut d'arguments non spécifiés doit être mentionné. Les commentaires concernant tous les arguments doivent être alignés sur le même taquet de tabulation.

 # tcl::HistRedo
 #
 # Allez chercher l’événement précédent ou spécifié,
 # exécutez le, et alors remplacez l'item courant de
 # "history" par cet événement.
 #
 # Arguments :
 # événement(optionnel) index de "history" item a
 # refaire. Valeur par défaut -1 qui veut dire
 # l'événement précédent;
 #
 # Résultats :
 # Le résultat est celui de la commande recommencée.
 # Également, remplace l'item en cours de la liste
 # "history" par l'événement qui vient d'être répété
 # proc tcl::HistRedo {{event -1}} {
 #     ...
 # }

Figure 2. Les commentaires et les déclarations d'une en-tête de procédure.

Résultats : La dernière partie de l'en-tête décrit les valeurs renvoyées par la procédure. Le type et l'utilisation projetée du résultat doivent être décrits. Cette section doit aussi faire état des effets de bord suffisamment significatifs pour être mentionnés.

Le fichier tclProcHead contient un patron d'en-tête de procédure qui devrait être utilisé comme base pour toute nouvelle commande de Tcl. Respectez très exactement la syntaxe de la Figure 2 (même indentation, double tiret après le nom de la procédure, etc..)

SECTION 4.4 Déclarations de procédures

La déclaration de procédure doit aussi suivre la syntaxe de la Figure 2. Notez que la procédure est définie en dehors de la commande d'espace des noms qui définit la liste d'exportation et les globales de l'espace de nom. La première ligne le mot-clef de la procédure, le nom de la procédure, et une liste des arguments. Si il y a de nombreux arguments ils peuvent déborder sur des lignes additionnelles (voyez les section 6.1 et 6.3 pour les informations concernant l'indentation).

SECTION 4.5 L'ordre des paramètres

Les paramètres de procédures peuvent se diviser en trois catégories. Les paramètres "in" (dedans) ne passent d'information qu'a l'intérieur de la procédure (soit directement ou en pointant sur des informations lues par la procédure). Les paramètres "out" (dehors) pointent vers des objets dans la mémoire de l'appelant que la procédure modifie, comme le nom d'une variable que la procédure va modifier. Les paramètres "in-out" opèrent des deux manières. Ci dessous un ensemble de règles permettant de décider de l'ordre des paramètres pour une procédure.

1. Normalement les paramètres doivent apparaître dans l'ordre "in", "in/out", "out", sauf quand les règles ci-dessous s'imposent.

2. Si un argument est en fait une sous-commande pour la commande alors il doit être le premier argument de la commande.

Par exemple :

 proc graph::tree {subCmd args} {
     switch $subCmd {
         add {
             eval add_node $args
         }
         draw {...

3. Si il existe un groupe de procédures, qui toutes opèrent sur un argument d'un type particulier, tel que le chemin d'un fichier ou le chemin d'un widget, il faudra que cet argument soit le premier argument pour chacune des procédures du groupe ci-dessus (ou après l'argument de la sous-commande)

SECTION 4.6 Corps des procédures

Le corps d'une procédure suit la déclaration. Voyez la section 6 pour les conventions de codage qui gouvernent les corps de procédures. Les accolades qui enferment le corps de la procédure doivent être sur des lignes différentes; comme le montre la Figure 2, même si le corps de la procédure est vide.

SECTION 5 Conventions d'attribution de noms

Choisir des noms est un des aspects les plus importants de la programmation. De bons noms clarifient la fonction d'un programme et réduisent le besoin d'une autre documentation. Des noms médiocres aboutissent à l'ambiguïté, la confusion et l'erreur. Cette section donne quelques principes généraux à suivre pour choisir des noms et énumère les règles particulières pour la syntaxe des noms, tel que la mise en majuscule.

SECTION 5.1 ''Considérations générales""

Le nom idéal pour une variable est celui qui communique instantanément autant d'information que possible concernant l'objet de la variable à laquelle il se réfère. Quand vous choisissez des noms, soyez votre propre avocat du diable et voyez si il est possible qu'un nom puisse être mal interprété ou confondu. Voici quelques points à envisager.

1. Êtes vous cohérent ? Employez partout le même nom pour désigner la même chose. Par exemple, à l'intérieur du code manipulant des "bindings" standards dans les widgets de Tk, "w" est un nom standardisé qui s'applique toujours à la fenêtre associée avec l'événement courant.

2. Si quelqu'un voit le nom hors de son contexte, pourra t il réaliser ce qu'il représente, ou pourra t il le confondre avec quelque chose d'autre? Par exemple, le nom de procédure "buildStructure" pourrait être confondu avec quelque autre partie du système. Un nom comme "buildGraphNode" décrit simultanément à quelle partie du système il appartient et à quoi, probablement il sert.

3. Ce nom peut il être confondu avec un autre nom ? Par exemple, c'est probablement une erreur d'avoir deux variables "str" et "string" dans le même procédure. Cela sera difficile pour quiconque de se rappeler laquelle est laquelle. Il vaudrait mieux changer les noms afin qu'ils reflètent leurs fonctions. Par exemple, si les chaînes sont utilisées comme source et comme destination pour une opération de copie, nommez les "src" et "dst".

4. Le nom est il si générique qu'il ne transmette aucune information ? La variable "str" du paragraphe précédent est un exemple de cela; changer son nom en "src" rend le nom moins générique et par conséquent transmet plus d'information.

SECTION 5.2 Règles de syntaxe fondamentales

Ci dessous vous trouverez quelques règles particulières régissant la syntaxe des noms. Veuillez suivre, précisément, ces règles, car elles rendent possible la détermination de certaines propriétés d'une variable simplement à partir de son nom.

1. Les noms exportés aussi bien pour les variables que pour les procédures doivent toujours commencer par une lettre minuscule. Les procédures et les variables qui sont prévues pour servir seulement avec le paquet courant ou l'espace de nom doivent commencer avec une lettre majuscule. Nous choisissons les minuscules pour les symboles exportés car il est possible qu'ils soient couramment utilisés à la ligne de commande et il est bon qu'ils soient faciles à écrire.

Par exemple:

 # "CountNum" est une variable privée
 set CountNum 0
 # La fonction "addWindow" est publique
 proc addWindow {} {...
 # "newWindow" est une interface publique dans l'espace de noms "spectcl"
 proc spectcl::newWindow {} {...

2. Dans des noms multi-mots, la première lettre de chaque mot suivant est en majuscule. N'employez ni tirets ni tirets bas comme séparateurs entre les mots constituant un nom.

 set numWindows 0

3. Toute variable dont la valeur se réfère à une autre variable doit avoir un nom qui se termine en "Nom". En outre, le nom doit également indiquer à quel type de variable il se réfère. Ces noms sont souvent utilisés pour les arguments de procédures qui prennent un nom de variable :

 proc foo::Bar {arrayName} {
     upvar 1 $arrayName array
     ...
 }

4. Les variables qui contiennent du code Tcl qui va être évalué doivent avoir leurs noms terminés en "Script"

 proc log::eval {logScript} {
     if {$Log::logOn} {
         set result [catch {eval $logScript} msg]
         ...

5. Les variables qui contiennent une commande Tcl partielle et qui doivent se voir ajouter des arguments additionnels avant de pouvoir être un script valide doivent avoir leurs noms terminés en "Cmd"

 foreach scrollCmd $listScrollCmds {
     eval $scrollCmd $args
 }

SECTION 6 Conventions de codage de bas niveau

Cette section décrit plusieurs règles syntaxiques pour écrire du code Tcl de bas niveau. Ces règles permettent de s'assurer que l'ensemble du code en Tcl respecte le même style, et elles interdisent certaines constructions déroutantes de code.

SECTION 6.1 Les indentations sont de 4 espaces

Chaque niveau d'indentation doit être de 4 espaces. La plupart des éditeurs courants permettent de régler des indentations de 4 espaces. Assurez vous que votre éditeur utilise bien 4 espaces pour les indentations plutôt que des tabulations de 4 espaces de large; si vous utilisez cette dernière manière alors vos indentations apparaîtront, dans d'autres éditeurs, d'une largeur de 8 espaces.

SECTION 6.2 Les commentaires du code occupent des lignes entières

Les commentaires qui documentent du code devraient occuper des lignes entières plutôt que d'être rattachés à la fin des lignes de code. La raison en est, qu'il est difficile de lire des commentaires cote à cote, particulièrement, lorsque les expressions se voisinant sont assez longues pour qu'il y ait recouvrement de ces commentaires cote à cote. Il est également facile de placer du code à un endroit qui pourrait causer des erreurs. Les commentaires doivent avoir exactement la structure montrée dans la figure 3, avec une ligne blanche avant et après le commentaire. La première ligne vide peut être omise si le commentaire est au début d'un bloc, comme c'est le cas dans le second commentaire de la figure 3. L'indentation de chaque commentaire doit être au même niveau que celle du code qui l'entoure. Utilisez un Anglais (Français) correcte dans les commentaires: écrivez des phrases complètes, La première lettre de chaque phrase doit être une lettre majuscule, et ainsi de suite.

 #Si nous fonctionnons sur une plate-forme Macintosh
 #alors nous pouvons partir du principe que les sources
 #se trouvent dans le "resource fork" de notre application
 #nous n'aurons donc pas à les chercher.
 if {$tcl_platform(platform) == "macintosh"} {
     return
 }
 foreach dir $dirList {
     #Si la source réussit alors nous sommes faits.
     if {![catch {source [file join $dir file.tcl]}]} {
         break
     }
 }

Figure 3. Les commentaires dans le code ont la forme ci-dessus, utilisant des lignes complètes, avec les dièses alignés, le commentaire occupe au minimum une ligne entière avec des lignes blanches entourant le commentaire(sauf que la ligne blanche du début peut être omise si le commentaire se situe au début d'un bloc de code)

SECTION 6.3 Les prolongations de lignes doivent être indentées de 8 espaces

Vous devez utiliser des prolongations de lignes pour vous assurer qu'aucune ligne ne dépasse, en longueur, 80 caractères. Les prolongations de lignes doivent être indentées de 8 espaces afin que l'on ne puisse pas les confondre avec un bloc imbriqué. Choisissez une position appropriée pour couper vos lignes afin que la prolongation n'obscurcisse pas la structure de l'expression. Par exemple, si l'appelle d'une procédure nécessite des prolongations de lignes, essayez d'éviter les situations ou un argument unique recouvrirait plusieurs lignes. Si les tests pour une commande "if" ou une commande "while" recouvrent plusieurs lignes, essayez de mettre, si possible, chaque ligne au même niveau d'imbrication des parenthèses et/ou des crochets. J'essaie de commencer chaque prolongation de ligne par un opérateur tel *, &&, ou ||; cette pratique met en évidence que la ligne est une prolongation, car une nouvelle expression ne commencerait jamais avec de tels opérateurs.

SECTION 6.4 Seulement une commande par ligne

Dans la page, vous devez n'avoir qu'une seule commande de Tcl par ligne. N'utilisez pas le point-virgule pour placer de nombreuses commandes sur la même ligne. Ceci facilite la lecture du code et aide à la mise au point (débogage).

SECTION 6.5 Les accolades : { vont à la fin de la ligne

Des accolades ouvertes ne peuvent pas apparaître, en Tcl, sur les lignes par elles même. Elles devraient, plutôt, être placés à la fin de la ligne précédente. Des accolades fermée sont indentées au même niveau que le code enveloppant, c est à dire, quatre espaces de moins que les expressions qu'elles enferment. Cependant, vous devez toujours utiliser des accolades plutôt que tout autre mécanisme générateur de listes qui fonctionnerait dans le langage Tcl. Cela aidera à rendre le code plus lisible, évitera des effets de bords non voulus et, dans de nombreux cas, générera, avec le compilateur de Tcl, un code plus rapide.

Les structures de contrôle doivent toujours employer des accolades, même si il n'y a qu'une seule expression dans le bloc. Par conséquent vous ne devriez pas écrire ce type de code :

 if {$tcl_platform(platform) == "unix"} return

mais plutôt :

 if {$tcl_platform(platform) == "unix"} {
     return
 }

Cette approche déconcentre le code, mais évite les erreurs potentielles telles que des substitutions Tcl non voulues. Elle facilite également l'écriture de points d'arrêts dans un débogueur, puisqu'elle garantit que chaque expression est sur une ligne séparée et peut être nommée séparément.

SECTION 6.6 Mettez les expressions entre parenthèses

Employez des parenthèses autour de chaque sous expression dans une expression afin de mettre en évidence quel est l'ordre d'évaluation de l'expression (un lecteur de votre code ne devrait pas avoir à se rappeler les règles de priorité de Tcl.)

par exemple n'écrivez pas :

 if {$x > 22 && $y <= 47} ...

écrivez plutôt:

 if {($x > 22) && ($y <= 47)} ...

SECTION 6.7 Employez toujours l'expression "return"

Vous devez toujours employer explicitement l'expression "return" pour renvoyer des valeurs d'une procédure de Tcl. Par défaut Tcl renverra la valeur de la dernière expression exécutée dans une procédure Tcl comme étant la valeur de retour de la procédure, ce qui conduit souvent à se tromper sur l'origine du résultat. De plus, vous devez utiliser "return" sans argument pour les procédures dont les résultats sont ignorés. Fournir ce "return" accélérera, en fait, votre application avec le nouveau compilateur de Tcl

Par exemple, n'écrivez pas votre code ainsi :

 proc foo {x y} {
     if {$x < 0} {
         incr x
     } else {
         expr $x + $y
     }
 }

Mais plutôt écrivez ceci :

 proc foo {x y} {
     if {$x < 0} {
         return [incr x]
     } else {
         return [expr $x + $y]
     }
 }

Pour les procédures Tcl qui n'ont pas de valeur de retour, une simple commande "return" sans arguments sera placée à la fin de la procédure.

SECTION 6.8 Les commandes "switch"

La commande switch doir être formatée comme ci-dessous. Utilisez toujours l'option "--" pour éviter que la chaîne soit confondue avec une option. Ceci peut se produire quand la chaîne est générée par l'utilisateur. Des commentaires peuvent être ajoutés sur la même ligne que le motif pour commenter le cas du motif. Les commentaires cas par cas, doivent être alignés sur le même taquet de tabulation et doivent être à l'intérieur des accolades. Remarquez que ceci est une exception aux conventions standards de commentaires.

 switch -regexp -- $string {
     plus -
     add {
         # Do add task
         ...
     }
     subtract {
         # Do subtract case
         ...
     }
     default {
         ...
     }
 }

SECTION 6.9 Les commandes "if"

N'employez jamais le mot "then" d'une commande "if". C'est du sucre syntaxique qui n'est pas vraiment très utile. Cependant, le mot "else" doit toujours être utilisé parce qu'il transmet une information sémantique et qu'il est plus proche du langage C.

En voici un exemple :

 if {$x < 0} {
     ...
 } elseif {$x == 0} {
     ...
 } else {
     ...
 }

SECTION 7 Documentation du code

Le but de la documentation est de gagner du temps et de faire moins d'erreurs. Typiquement, on se sert de la documentation pour deux usages. Premièrement, les gens liront la documentation pour déterminer comment se servir de votre code. Par exemple, ils liront les en-tête de procédures pour savoir comment les appeler. Dans l'idéal, les gens devraient avoir à apprendre aussi peu que possible de votre code afin de pouvoir s'en servir correctement. Deuxièmement, les gens liront la documentation pour comprendre comment votre code fonctionne en interne, afin de pouvoir soit corriger des bogues soit ajouter de nouvelles caractéristiques; la encore, une bonne documentation leur permettra de faire leurs corrections ou leurs améliorations en ayant besoin d'en apprendre un minimum au sujet de votre code. Plus de documentation n'est pas nécessairement un mieux: patauger à travers des pages de documentation peut n’être pas plus facile que de déchiffrer le code. Essayez de choisir les aspects les plus importants, ceux qui permettront aux gens de comprendre votre code et concentrez vous sur ces aspects dans votre documentation.

SECTION 7.1 Documentez les choses qui auront l'effet le plus large

Les choses les plus importantes à documenter sont celles qui affectent de nombreuses parties d'un programme. C 'est ainsi qu'il est essentiel que chaque interface de procédure, chaque déclaration de structure, et chaque variable globale soient clairement documentées. Si vous avez omis de documenter l'un de ces éléments, il faudra alors chercher à déterminer toutes les utilisations possibles de cet élément, pour déterminer comment l'élément lui même est supposé fonctionner, ce qui est coûteux en temps et favorise les erreurs.

D'un autre coté, les choses qui n'ont qu'un effet local peuvent ne pas nécessiter une documentation importante. Par exemple, dans des procédures courtes, je n'écris pas, en général, de documentation expliquant les variables locales, si dans son ensemble, la fonction de la procédure a été expliquée et si il n'y a que peu de code dans la procédure, et si les variables ont des noms significatifs, alors il sera facile de déterminer comment elles sont utilisées. D'un autre coté, pour des procédures longues avec de nombreuses variables, je documente, en général, les variables clés. De même, quand j'écris des procédures courtes je n'ai généralement pas de commentaire dans le code de la procédure: l’en-tête de la procédure fournit suffisamment d'information pour déterminer ce qui se passe. Pour de longues procédures, je place un bloc de commentaires avant chaque partie principale de la procédure afin de clarifier l'ensemble du flux à travers la procédure.

SECTION 7.2 Ne répétez pas simplement ce qu'il y a dans le code

L'erreur la plus courante que je rencontre dans la documentation (hormis le fait qu'il n'y en ait pas du tout) est qu'elle répète ce qui est évident à la lecture du code, tel que cet insignifiant (mais désespérément courant) exemple :

 #Incrémentez i.
 incr i

La documentation doit fournir une information de haut niveau au sujet de l'ensemble de la fonction du code, aidant le lecteur à comprendre ce qu'un ensemble complexe de déclarations veut réellement dire. Par exemple, le commentaire

 #Sondez le tableau pour voir si le symbole existe

est probablement bien plus utile que

 #Bouclez avec chaque index du tableau, prenez la
 # troisième valeur de la liste dans le contenu pour
 # déterminer si elle contient le symbole que nous recherchons.
 # Affectez le résultat au symbole si nous le trouvons.

Tout du deuxième commentaire est probablement évident à la lecture du code qui le suit. Un autre élément à prendre en compte dans vos commentaires est le choix des mots. Employez des mots qui diffèrent des mots qui apparaissent dans les noms des variables et/ou des procédures. Par exemple le commentaire

 #"EchangePanneaux"--
 #
 # Échangez les panneaux
 #...

n'est pas un commentaire très utile. Le tout du commentaire est déjà évident à partir du nom de la procédure. Voici un commentaire bien plus utile:

 #"EchangePanneaux"
 #
 # Extournez l'actuel panneau d' IU du "frame" parent et
 # remplacez le avec le "frame" nouvellement spécifié.
 # Assurez vous que le nouveau panneau s'ajuste bien
 # dans l'ancien "frame" et si besoin est, redimensionnez

Ce commentaire vous dit ce pourquoi vous pourriez vouloir utiliser la procédure, en plus de ce que fait cette procédure, ce qui rend ce commentaire bien plus utile.

SECTION 7.3 Documentez chaque chose en un seul et unique endroit

Les systèmes évoluent dans le temps. Si quelque chose est documenté en plusieurs endroits, alors il sera difficile de maintenir la documentation à jour au fil des changements du système. Essayez plutôt de documenter chaque décision importante de conception en un seul et unique endroit, aussi près que possible du code qui met en œuvre cette décision de conception. La documentation principale pour chaque procédure se trouve dans son en-tête. Il n'est pas nécessaire de répéter à nouveau cette information dans le corps de la procédure (mais vous pouvez avoir des commentaires additionnels dans le corps de la procédure pour compléter des détails qui n'auraient pas été décrits dans l'en-tête de la procédure). Si une procédure de bibliothèque est parfaitement documentée dans un article de manuel, alors je peux écrire une en-tête très simplifiée pour la procédure, faisant simplement référence à l'article du manuel. Un autre aspect c’est que chaque décision importante de conception devra être documentée au moins une fois. Si une décision de conception est utilisée en plusieurs endroits, il sera, alors, probablement difficile de choisir un endroit central pour la documenter. Essayez de trouver une structure de données ou une procédure clé ou vous pourrez placer le corps principal de vos commentaires ; puis référencez ce corps de commentaires dans les autres endroits ou cette décision de conception est employée. Si rien de tout ceci n'est possible, ajoutez un bloc de commentaires à la page d'en-tête d'un des fichiers qui met en œuvre cette décision.

SECTION 7.4 Écrivez du code clair

Le meilleur moyen pour produire un système bien documenté c'est encore d'écrire du code clair et simple. De cette manière il n'y aura pas grand chose à commenter. Si le code est clair, cela signifie que son fonctionnement s'explique par quelques idées, peu nombreuses et simples; tout ce que vous avez à faire, c est de documenter ces idées clés. Quand vous écrivez du code, demandez vous si derrière ce code il y a un concept simple, sinon, peut être devriez vous repenser votre code. Si, pour expliquer un morceau de code, il faut une documentation pléthorique, alors, c 'est signe que vous n'avez pas trouvé une solution claire au problème.

SECTION 7.5 Documentez au fur et à mesure que vous avancez

Il est extrêmement important que votre documentation soit écrite au fur et à mesure que vous codez. Il est extrêmement tentant de laisser la documentation de coté jusqu'à la fin, après tout, le code va changer, pourquoi, alors, perdre du temps à documenter maintenant ce qui va changer plus tard? Le problème c'est que la fin ne vient jamais -- il y a toujours plus de code à écrire. Également, plus vous accumulez de code non commenté, plus il est difficile de trouver l'énergie nécessaire pour le commenter. Alors, tout simplement, vous écrivez encore du code non documenté. J ai vu nombre de personnes démarrer un projet avec l'intention bien arrêtée de revenir en arrière, à la fin, et d'écrire toute la documentation, mais jamais je n'en vu qui l'aient vraiment fait.

Si vous produisez la documentation au fur et à mesure, cela n'allongera pas substantiellement votre temps d'écriture et vous n'aurez pas à vous soucier d'avoir à le faire plus tard. De plus, le meilleur moment pour documenter du code c'est quand les idées clés sont fraiches dans votre esprit, ce qui est le cas au moment d'écriture du code. Quand j'écris un nouveau code, j'écris tous les commentaires d'en-tête pour un groupe de procédures avant de compléter les corps de procédures. De cette manière je peux réfléchir sur l'ensemble de la structure et voir comment les éléments s'organisent entre eux avant d'être enlisé dans les détails des procédures individuelles.

SECTION 7.6 Documentation de situations difficiles

Si ce code n'est pas évident, c est à dire que sa structure et son exactitude dépendent d'informations qui ne seront pas limpides pour quelqu'un qui lira ce code pour la première fois, assurez vous d'avoir commenté l'information non évidente. Un bon indicateur d'une situation difficile c'est une bogue. Si vous découvrez, en réglant une bogue, une propriété subtile dans votre programme, assurez vous d'avoir ajouté un commentaire explicitant et le problème et sa solution. Bien évidemment l'idéal serait que vous régliez la bogue en éliminant ce comportement subtile, mais ce n'est pas toujours possible.

SECTION 8 Procéder à des tests

L'un des environnements ou Tcl se distingue c'est celui des tests. Bien que traditionnellement Tcl ait été surtout utilisé pour tester du code C, il est aussi performant à tester du code Tcl. A chaque fois que vous écrivez un nouveau code, vous devriez également écrire des scripts Tcl de tests qui vont avec ce code et vous devriez sauvegarder les tests dans des fichiers afin qu'ils puissent être exécutes à nouveau plus tard. Écrire des scripts de tests n'est pas aussi fastidieux qu'on pourrait le croire. Si vous développez votre code prudemment vous tester déjà beaucoup; il ne vous reste plus qu'à écrire vos tests dans un fichier qui permettra de les réutiliser plutôt que de les écrire inter-activement car dans ce dernier cas après exécution ils disparaissent.

SECTION 8.1 Principes

Les tests devraient être organisés en fichiers de scripts, où chaque fichier contiendrait un ensemble de tests connexes. Les tests individuels devraient être basés sur le test de procédure, exactement comme dans l'ensemble des tests de Tcl Tk. Ci dessous deux exemples

 test expr-3.1 {floating-point operators} {
     expr 2.3*.6
 } 1.38

 test expr-3.2 {floating-point operators} {unixOnly} {
     list [catch {expr 2.3/0} msg] $msg
 } {1 {divide by zero}}

"test" est une procédure définie dans un fichier de scripts dénommé "defs", qui est lu et évalué par chaque fichier de test. "test" prend quatre ou cinq arguments, un identificateur de test, une chaine décrivant le test, un argument optionnel décrivant les conditions d'exécution du test, un script de test, et le résultat attendu du script. "test" évalue le script et s'assure qu'il produit le résultat escompté. Sinon, il imprime un message du type qui suit:

 ==== expr-3.1 floating-point operators (expr-3.1 opérateurs en virgule flottante)
 ==== Contents of test case: (contenus du cas testé)
 expr 2.3*.6
 ==== Result was: (le résultat est)
 1.39
 ---- Result should have been: (le résultat aurait du être)
 1.38
 ---- expr-3.1 FAILED (ECHEC)

Pour exécuter un ensemble de tests, vous démarrez l'application et vous lisez et évaluez un fichier de tests. Si tout s'est bien déroulé aucun message n’apparaîtra, si des erreurs sont détectées, un message sera imprimé pour chaque erreur rencontrée.

L'identificateur de test, tel que "expr-3.1", est imprimé quand une erreur survient. Ceci peut servir à effectuer des recherches dans un script de test pour localiser l'origine de l'échec du test. La première partie de l'identificateur, telle que "expr", devrait être identique au nom du fichier de test, à ceci près que le fichier de test devrait avoir comme extension ".test", tel que "expr.test". Les deux nombres vous permettent de diviser vos textes en groupes. Les tests d'un groupe particulier (c est à dire tous les tests d'expression "expr-3.n") se rapportent à une unique sous-caractéristique, telle qu'une unique procédure. Les tests devraient apparaître dans le fichier de test dans le même ordre que celui de leur numérotation.

Le nom du test, tel que "opérateurs en virgule flottante", est imprimé quand des erreurs se produisent. Il procure des informations lisibles par un être humain concernant la nature générale du test.

Avant que vous n’écriviez des tests, je vous suggère de parcourir quelques fichiers des tests pour Tcl Tk afin que vous puissiez voir comment ils sont structurés. Vous pourriez également parcourir les fichiers README (LISEZ MOI) dans les répertoires de Tcl et Tk afin de découvrir de nouvelles caractéristiques dont certaines fournissent des sorties plus détaillées ou d'autres qui limitent l'ensemble de tests qui sont exécutés.

SECTION 8.2 Organiser les tests

Organiser vos tests pour qu'ils correspondent au code en cours de contrôle. La meilleure façon de le faire est de disposer d'un fichier de tests correspondant à chaque fichier de code source, avec le nom du fichier de test dérivé de manière évidente du nom du fichier source (c'est à dir "http.tests" contient des tests pour le fichier code "http.tcl"). Au sein du fichier de tests, ayez un groupe de tests pour chaque procédure (par exemple, tous les tests "http-3.n" dans "http.tests" sont destinés à la procédure "http::geturl"). L'ordre des tests dans un groupe doit être le même que l'ordre du code dans la procédure. Cette façon de procéder permet de trouver plus facilement les tests correspondant à un bloc de code particulier et facilite également l'addition de nouveaux tests au fur et à mesure des modifications du code. L’ensemble des tests pour Tcl a été écrit il y a bien longtemps et utilise un style différent avec un fichier pour chaque commande de Tcl ou pour chaque groupe de commandes connexes, quant aux tests ils sont groupés au sein du fichier par sous-commandes ou caractéristiques. Dans cette approche la relation entre les tests et les blocs de code particuliers est bien moins évidente, il est donc plus difficile d'effectuer la maintenance des tests au fur et à mesure de l'évolution du code. Je déconseille d'utiliser cette approche pour de nouveaux tests.

SECTION 8.3 Couverture

Quand vous écrivez des tests, vous devriez essayer d'exécuter, au moins une fois, chaque ligne de code. Il y aura parfois du code que vous ne pourrez exécuter, comme par exemple du code qui fait sortir de l'application, mais de telles situations sont rares. Vous pouvez rencontrer des difficultés à exécuter certains blocs de code parce que les commandes Tcl disponibles ne mettent pas à votre disposition un contrôle suffisamment fin permettant de générer tous les chemins possibles d'exécution. Dans de telles situations écrivez simplement une ou plusieurs nouvelles commandes de Tcl aux fins de tester. Il vaut mieux tester une fonction directement plutôt que de se fier, pour tester, à un quelconque effet de bord qui pourra être modifié au fil du temps. Pratiquez de la même manière pour votre propre code, en disposant d'un fichier excédentaire contenant des commandes additionnelles aux fins de tester.

Il ne suffit pas de simplement vous assurer que chaque ligne de votre code est exécutée par vos tests. Il faut en plus que vos tests discriminent le code qui s'exécute correctement du code qui n'est pas correct. Par exemple, écrivez des tests qui vont s' assurer que que les branchements "then" et "else" de chaque instruction "if" sont mis en œuvre avec les conditions correctes. Pour une boucle, exécutez des tests différents qui vont faire exécuter la boucle zéro fois, une fois, et deux ou plusieurs fois. Si un bloc de code enlève un élément d'une liste, essayez des situations ou l'élément qui va être enlevé est le premier élément, le dernier élément, l'unique élément et ni le premier ni le dernier élément. Essayez de trouver tous les emplacements ou divers blocs de code inter-réagissent de manières inhabituelles et testez les différentes interactions possibles.

SECTION 8.4 Corriger les bogues

A chaque fois que vous trouvez une bogue dans votre code cela signifie que l'ensemble des tests n'était pas complet L’ajout de nouveaux tests qui détectent l’existence de cette bogue fait partie de la correction de la bogue; Je recommande que les tests soient écrits après avoir localisé la bogue mais avant de l'avoir corrigée. De cette manière vous pouvez vérifier que la bogue apparait avant que vous n'ayez installé la correction et que cette bogue n'apparait pas après, ainsi vous saurez que vous avez vraiment réparé quelque chose. Utilisez les bogues pour affiner votre approche des tests; à l’avenir quand vous écrirez des tests, pensez à ce qu’il vous serait possible de faire différemment afin que des bogues de cette nature ne restent pas indécelables.

SECTION 8.5 Caractéristiques problématiques

J'emploie aussi les tests afin d'illustrer le besoin d'employer du code problématique. Si un bloc de code a une structure inhabituelle, et plus particulièrement si le code est difficile à expliquer, j'essaie d'écrire des tests supplémentaires qui échoueront si le code est écrit de la façon évidente plutôt qu'écrit de manière problématique. De cette façon, si plus tard un nouvel intervenant ne comprenant pas la documentation du code, décide que la structure complexe n'est pas nécessaire et réécrit le code de la façon plus simple (mais incorrecte), le test échouera et cet intervenant aura ainsi le loisir d'utiliser le test pour comprendre pourquoi il était nécessaire que le code ait la forme qu'il avait. Des tests illustratifs ne remplacent pas une bonne documentation, mais ils procurent un complément utile.

SECTION 8.6 Indépendance des tests

Essayez de rendre les tests indépendant les uns des autres, de façon que chaque test puisse être compris isolément. Par exemple, un test ne devrait pas dépendre de commandes exécutées dans un test précédent. Ceci est important car un ensemble de tests permet que les tests soient exécutés sélectivement. Si les tests devaient dépendre les uns des autres, alors de fausses erreurs seraient signalées lorsque quelqu'un exécuterait certains tests et pas les autres.

Pour des raisons d'opportunité, vous pouvez exécuter quelques instructions dans le fichier de tests pour définir une configuration et ensuite exécuter quelques tests basés sur cette configuration. Si vous faites cela, mettez le code de définition de configuration en dehors des appels aux procédures de test ainsi, il s'exécutera toujours normalement si les tests individuels ne sont pas exécutés. Je suggère de maintenir une structure très simple consistant en une définition de configuration suivie d'un groupe de tests. N'exécutez pas quelques définitions, exécutez quelques tests, modifiez légèrement la configuration, exécutez quelques tests supplémentaires, modifiez à nouveau la configuration, et ainsi de suite. Si vous procédez ainsi, les gens auront du mal à appréhender en quoi consiste la configuration à chaque point et quand ils vont ajouter des tests, plus tard, ils vont probablement détruire la configuration.

SECTION 9 Divers

SECTION 9.1 Questions de portabilité

Écrire des scripts portables en Tcl est en fait très simple car Tcl lui-même est tout à fait portable. Cependant, des questions surgissent qui peuvent exiger d'écrire du code spécifique à chaque plate-forme. Pour soumettre votre code à condition, vous devriez utiliser le tableau "tcl_platform" pour déterminer les différences propres à chaque plate-forme. Vous devriez éviter d'employer la variable "env" sauf si vous avez déjà déterminé sur quelle plate-forme vous travaillez via le tableau "tcl_platform".

Comme Tcl/Tk est devenu plus multiplate-forme nous avons ajouté des commandes qui aident à rendre votre code plus portable. Les erreurs de portabilité les plus courantes proviennent de suppositions concernant les noms et emplacements de fichiers. Pour éviter de telles erreurs, employez toujours les commandes "file join" et "list", afin de pouvoir gérer des caractères et des espaces de séparation de fichiers dans les noms de fichiers. Dans Tk vous devriez toujours utiliser les boites de dialogue de haut niveau qui sont fournies plutôt que de créer les vôtres. Les commandes "font" et "menu" ont aussi été revues et améliorées pour faciliter l'écriture de code multiplate-forme.

SECTION 9.2 Fichiers des modifications

Chaque paquet devrait inclure un fichier appelé "modifications(changes)" qui journalise toutes les modifications substantielles opérées au sein du paquet. Le fichier des modifications fournit aux utilisateurs un moyen de déterminer ce qu'il y a de nouveau dans chaque nouvelle version. quelles bogues ont été corrigées, et quels problèmes de compatibilité peuvent avoir été introduits par la nouvelle version. Le fichier des modifications doit être tenu dans l'ordre chronologique. Ajoutez lui des commentaires courts à chaque fois que vous opérez une modification. Ci dessous un exemple extrait du fichier des modifications de Tk :

 5/19/94(réparation de bogue) Les "canvas" n'ont pas généré
 du Postscript correct pour du texte pointillé.(RJ)

 5/20/94(nouvelle caractèristique) Ajouté la commande "bell"
 pour faire sonner le haut parleur d'écran.(JO)

 5/26/94(suppression de caractéristiques) Supprimer la prise en compte de "fill"
 mode de justification de "Tk_GetJustify.(SS)

        *** INCOMPATIBILITE POSSIBLE ***

Les commentaires dans le fichier des modifications peuvent être relativement succincts; une fois que quelqu'un a trouvé un changement qui est pertinent, il peut toujours se référer aux articles du manuel ou au code pour en savoir plus. Assurez vous d'avoir mis l'accent sur les modifications qui génèrent des problèmes de compatibilité, afin que les intéressés puissent parcourir le fichier des modifications rapidement et localiser les incompatibilités. Assurez vous également d'ajouter vos initiales aux commentaires afin que les gens qui parcourent le journal puissent savoir qui a effectué une modification particulière.


# Traduction terminée le 22/07/07 (si vous faites des corrections, merci, dites le moi, mon email est ici : Jerome Suchod)