Vous trouverez ci-dessous une étude de cas sur l’utilisation du débogueur JSL pour résoudre un problème. Ceci est basé sur un script réel avec le problème spécifié. Si vous souhaitez voir le problème dans son contexte, j'ai créé un script - très simplifié par rapport à l'original - qui montre le problème. Si vous voulez jouer avec vous, vous pouvez télécharger DebuggerDemo-SolvingProblems.jsl à partir de l’échange de fichiers JMP (profil SAS gratuit à télécharger).
Bien que je décrive le script d'origine, les extraits de code et les images proviennent tous de cet exemple de script. Suivre!
Le problème
L'autre jour, un scripteur JSL qui avait un problème avec un script m'a été demandé de l'aide. Son script fonctionnait bien en anglais, mais un testeur exécutant son script en chinois simplifié avait des erreurs.
Le problème semblait être lié à la façon dont les chaînes étaient traitées en anglais par rapport au chinois: en particulier, les citations échappées ( \! " ) ont été laissés de côté.
En anglais, voici un exemple de chaîne construite:
"dt << Sélectionnez Où (dt: Numbers == 45 & dt: Pick Strings == \!" South \! ")"
En chinois, la chaîne ressemblait à ceci:
"dt << Sélectionnez Où (dt: Numbers == 45 & dt: Pick Strings == South)"
Notez les manquants \! "... \!" autour Sud , qui provoquait des erreurs lors de l’analyse de la chaîne et que cette valeur non citée ne pouvait pas être résolue.
Y avait-il un bogue dans JMP lors de la gestion des guillemets dans des chaînes dans des langues autres que l'anglais?
Premier coup d'oeil
Elle m'a envoyé le script et les données nécessaires à son exécution. Le script ne manquait que de 900 lignes et produisait un rapport interactif. Les 130 premières lignes ont été configurées, les lignes 131 à 886 ont défini des expressions, puis le reste du script a utilisé ces expressions.
La première chose que j'ai faite a été d'exécuter le script en anglais, puis en chinois, pour voir si j'avais le même problème. J'ai fait. Ensuite, je l'ai publié en français, ce qui a confirmé que le problème concernait une langue autre que l'anglais, pas seulement le chinois. J'ai passé le reste de mes tests en anglais et en français, car le français est plus facile à lire que le chinois.
POINTE: Il est facile de changer la langue dans laquelle vous exécutez JMP sous Windows. Sélectionnez Fichier> Préférences, puis sélectionnez la catégorie spécifique à Windows. En haut, sélectionnez une langue sous Langue d'affichage. Sur Macintosh, quittez d'abord JMP, puis ouvrez les Préférences Système (dans le menu Pomme) et sélectionnez la catégorie Langue et texte. Faites glisser une nouvelle langue en haut de la liste. Ne fermez pas cette fenêtre! Il définit la langue de votre ordinateur. Démarrez JMP et il s'exécutera dans la première langue de la liste. Lorsque vous avez terminé, quittez JMP et faites glisser l’anglais (ou la langue que vous utilisez généralement sur votre ordinateur) vers le haut. Vous pouvez maintenant fermer la fenêtre Préférences Système en toute sécurité.
La chaîne ci-dessus a été construite à l'aide de plusieurs lignes et toutes reposaient sur un codage assez complexe qui aurait été difficile et fastidieux d'exécuter ligne à ligne, entrer et sortir de multiples expressions et comprendre ce que je cherchais.
L'exécution des lignes de création de chaîne appropriées (après que le script ait été exécuté une fois pour initialiser toutes ces variables) a donné les mêmes résultats dans toutes les langues, les citations échappées étant utilisées correctement. Cependant, les lignes formant la chaîne utilisaient les valeurs de deux tables de données plus une troisième construite à partir des deux premières. Il était très difficile de savoir d'un coup d'œil où toutes les variables utilisées étaient créées et renseignées.
En d'autres termes, c'était un travail pour le débogueur JSL!
Entrez le débogueur JSL
En exécutant JMP en anglais, j'ai ouvert le script et cliqué sur Debug. Comme j'avais déjà exécuté le script, toutes ses variables étaient répertoriées sous Globals. Et ils étaient nombreux - trop nombreux pour être suivis au fur et à mesure que je progressais dans le script. (J'aurais aussi pu découvrir cela en exécutant Afficher les globales () et en regardant le journal devenir très long.)
C’est tout ce que j’avais besoin de savoir à ce moment-là. J’ai donc quitté le débogueur JSL, puis arrêté et redémarré JMP pour que mon environnement soit maintenant complètement propre. J'ai ouvert le script et j'ai relancé le débogueur.
La chaîne en cours de construction m'intéressant, j'ai donc ajouté cette variable à ma liste de surveillance. Pour ce faire, j'ai sélectionné la variable dans le script comme indiqué dans le débogueur JSL, cliqué avec le bouton droit de la souris et sélectionné Ajouter une surveillance.

J'ai ajouté un point d'arrêt sur la première ligne une fois la partie configuration terminée (ligne 131 de l'original; ligne 34 de mon échantillon), et un autre point à la première ligne d'instruction «réelle» après la création de toutes les expressions (ligne 887 du original, cela n’existe pas dans mon échantillon). Pour ce faire, j'ai cliqué à côté du numéro de ligne dans le script affiché dans le débogueur.

POINTE: Un point d'arrêt ne fonctionnera que si vous le placez sur une ligne effectuant une action. Un point d'arrêt situé sur une ligne vierge, une ligne contenant uniquement une parenthèse fermée ou une ligne mise en commentaire sera ignoré.
J'ai exécuté la première partie «setup» et j'ai vu que ma variable de chaîne n'avait pas encore été créée. J'ai appris cela en un clic - beaucoup plus rapidement que si j'exécutais le script manuellement, ligne par ligne!
J'ai couru la deuxième partie, qui a simplement créé toutes les expressions.
Le moment était venu d'agir.
La “viande” du script était contenue au bas du script original, en seulement 10 lignes. La première partie était une boucle qui appelait un couple d'expressions (qui s'appelait expressions, qui appelait expressions, etc.). J'ai utilisé le bouton Pas à pas pour entrer dans chaque expression, pour savoir ce qui se passait.
POINTE: Utiliser Step Over quand une expression, une fonction définie par l'utilisateur ou Comprendre () sont appelés, exécute ce code dans son intégralité, retourne son résultat et place le point d'exécution à la ligne suivante. Si vous n’avez pas besoin de parcourir ligne par ligne, c’est un moyen rapide de sauter ce dont vous n’avez pas besoin. D'autre part, vous avez parfois besoin de voir exactement ce que font cette expression, cette fonction ou ce script inclus. Utilisez Step Into à la place et vous pourrez parcourir ce morceau de code ligne par ligne.
Résultats
Ce que j’ai découvert c’est que chaque morceau de la ficelle a été construit dans un Si () expression: Si la colonne avec l'information était un caractère, alors la valeur était citée avec les guillemets échappés; sinon, la valeur n'a pas été citée.
Cela signifiait également que, sur près de 900 lignes de code, je n'étais vraiment intéressé que par un petit bloc de 19 lignes (qui dépendait néanmoins des 800 autres lignes). Ces lignes sont recréées (et simplifiées) aux lignes 38 à 54 de mon échantillon.
J'ai changé JMP pour fonctionner en français, quitter et redémarrer, et relancé le débogueur.
Soudain, tout était clair ...
JMP est localisé! (Qui savait?)
Le problème n'était pas avec les assignations qui ont construit la chaîne. Le problème que j’ai vu immédiatement avec le débogueur est qu’en français, la condition dans Si () expression qui a déterminé si la colonne était caractère déterminé que la colonne était ne pas personnage. Pour les colonnes de caractères, le script a exécuté un point de code différent en français de celui en anglais.
En fait, la condition en français reviendrait toujours 0 . La pièce d'état du Si () expression est la suivante (lignes 40 et 48 de mon échantillon):
Analyser ( "dt:" || ColumnNames [ thisCol ] ) << Obtenir le type de données () == "Personnage"
En anglais, col << Obtenir le type de données () résultats "Personnage" pour une colonne de caractères. En français, ça revient "Caractère" , qui ne sera jamais évalué comme étant égal à "Personnage" .
col << Obtenir le type de données () renvoie toujours une réponse localisée.
Comme il n’a jamais été déterminé que la colonne en question était égale à "Personnage" lorsqu'elle est exécutée en chinois (ou en français ou dans une langue autre que l'anglais que JMP prend en charge), la chaîne est construite comme si la valeur de la cellule était numérique. Et c’est la raison pour laquelle la chaîne en anglais avait échappé aux guillemets et non en chinois.
Remarque: Bien que le débogueur JSL n’affiche pas les résultats de la << Obtenir le type de données () message - seulement le résultat de la comparaison - je pouvais facilement quitter le débogueur, et sélectionner et exécuter Analyser ( "dt:" || ColumnNames [ thisCol ] ) << Obtenir le type de données () pour voir ce qui a été réellement rendu. Le débogueur m'a permis de trouver le problème rapidement et sans douleur.
Appel à l'action
Il n'y a pas de bogue dans JMP: cela fonctionne comme prévu. Le script n'a besoin que d'un petit changement pour fonctionner dans n'importe quelle langue.
Il existe plusieurs approches pour rendre le script convivial dans toutes les langues. Qu'est-ce que tu ferais? J'ajouterai l'approche que nous avons adoptée aux commentaires dans une semaine ou deux.