Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
2_programmation:macros:cette_commande_est_elle_definie [2021/01/07 19:23]
jejust Traduction partielle en français.
2_programmation:macros:cette_commande_est_elle_definie [2021/09/27 23:41] (Version actuelle)
bdumont Traduction et remaniement pour mettre les solutions modernes et fiables en premier
Ligne 1: Ligne 1:
-====== Comment tester si une commande est définie ? ======+====== Comment tester si une commande est définie? ======
  
-===== Méthodes traditionnelles ​=====+===== En TeX =====
  
-==== En TeX ====+Le programme <​latex>​\TeX{}</​latex>​ original, écrit par Donald Knuth, ne définit pas de commandes dédiées à cette tâche. Heureusement,​ [[1_generalites:​glossaire:​qu_est_ce_que_etex|ε-TeX]] définit deux primitives supplémentaires :​
  
-Voici ce qu'on trouve dans les anciennes macros écrites en <​latex>​\TeX{}</​latex>​ +  * ''\ifdefined''​ 
-pour tester l'existence d'une commande ​''​<//​commande//>​''​:+  * ''​\ifcsname cmd name\endcsname''​
  
-''​\ifx\<//​commande//>​\undefined<//​code à exécuter//>''​+Les deux commandes utilisées dans l'exemple qui suit produisent le même effet :
  
-(ceci exécute le code si la commande **n'​**existe **pas**, bien sûr).+<code latex> 
 +\ifdefined\foo 
 +  \message{\string\foo\space is defined}% 
 +\else 
 +  \message{no command \string\foo}% 
 +\fi 
 +
 +\ifcsname foo\endcsname 
 +  \message{\string\foo\space is defined}% 
 +\else 
 +  \message{no command \string\foo}% 
 +\fi 
 +</​code>​
  
 +However, after using the original LaTeX ''​\@ifundefined{foo}...'',​
 +the conditionals will detect the command as "​existing"​
 +(since it has been ''​\let''​ to ''​\relax''​) ; so it is important
 +not to mix mechanisms for detecting the state of a command.
  
-==== En LaTeX ====+===== En LaTeX =====
  
 Quand on programme en <​latex>​\LaTeX{}</​latex>,​ on peut directement utiliser Quand on programme en <​latex>​\LaTeX{}</​latex>,​ on peut directement utiliser
Ligne 21: Ligne 37:
 (''<//​cmd name//>''​ est le nom de la commande tout nu, **sans son antislash** ''​\''​). (''<//​cmd name//>''​ est le nom de la commande tout nu, **sans son antislash** ''​\''​).
  
-La macro ''​\@ifundefined'' ​utilise ce mécanisme:+Si vous utilisez une version de <​latex>​\LaTeX{}</​latex>​ antérieure à 2018, il faut éviter de mélanger du code qui utilise les primitives d'​ε-TeX avec du code qui utilise ​''​\@ifundefined'' ​(voir ci-dessous pourquoi). Comme cela peut se produire d'une extension à l'​autre,​ vous n'​êtes jamais à l'abri d'une erreur...
  
-<code latex> +Notez également que, même après 2018, <​latex>​\LaTeX{}</latexva toujours renvoyer "​vrai"​ si l'on utilise ​''​\@ifundefined'' ​avec une commande ​définie ​comme un alias de ''​\relax''​.
-\expandafter \ifx \csname cmd name\endcsname \relax +
-</code> +
-qui repose sur le fonctionnement de ''​\csname''​+
-si la commande ​n'​existe pas, il la crée comme alias de ''​\relax''​.+
  
 +===== Un peu d'​histoire =====
  
-===== Qu'est-ce qui ne va pas avec ces méthodes ? =====+On trouve dans d'​anciennes macros écrites en <​latex>​\TeX{}</​latex>​ le procédé suivant 
 +pour tester l'​existence d'une commande ''<//​commande//>'':​ 
 + 
 +''​\ifx\<//​commande//>​\undefined<//​code à exécuter//>'​'
  
-Using ''​\undefined''​ blithely assumes that the command is indeed not +(Ceci exécute le code si la commande **n'**existe **pas**bien sûr.)
-defined. ​ This isn't entirely safe; one could make the name more +
-improbable, but that may simply make it more difficult to spot a +
-problem when things go wrong. ​ LaTeX programmers who use the +
-technique will typically employ ''​\@undefined'​', ​adding a single +
-level of obscurity.+
  
-The original ​''​\@ifundefined'' ​mechanism had the unfortunate property of +Le fonctionnement de cette commande repose sur le principe que ''​\undefined'' ​n'est jamais défini (donc elle est égale à une autre commande non définie). Le problème est qu'il ne s'agit que d'une convention qui peut être ignorée par un autre auteur de macros il y donc toujours un risque que cette macro soit définie dans une extension chargée par l'​utilisateur... Utiliser ​''​\@undefined''​, comme on peut le voir dans certaines macros <​latex>​\LaTeX{}</​latex>,​ ne fait que déplacer le problème.
-polluting the name spaceeach test that turns out undefined adds a +
-name to the set TeX is holding, and often all those ''​\relax''​ +
-names serve no purpose whatever+
  
-David Kastrup offers the (rather tricky):+La macro ''​\@ifundefined'',​ elle, est définie dans le noyau de <​latex>​\LaTeX{}</​latex>,​ ce qui permet d'​éviter ce problème. Cependant, avant 2018, elle était définie de la manière suivante :
  
 <code latex> <code latex>
-{\expandafter}\expandafter\ifx \csname cmd name\endcsname\relax ​...+\expandafter \ifx \csname cmd name\endcsname \relax
 </​code>​ </​code>​
-which "​creates"​ the ''​\relax''​-command inside the group of the first 
-''​\expandafter'',​ therefore forgets it again once the test is done. 
-The test is about as good as you can do with macros. 
  
-The [[FAQ-etex|ε-TeX system]] system comes to our help hereit +Elle utilisait la propriété suivante de ''​\csname''​ 
-defines two new primitives:+si la commande n'​existe pas, elle est créée comme alias de ''​\relax''​. 
 +Cette approche présente deux inconvénients 
  
-  * ''​\ifdefined'', ​which tests whether a thing is defined (the negative of comparing with ''​\undefined'', ​as it were), and +  * Chaque utilisation de ''​\@ifundefined'​' ​avec un nom de commande qui n'existe pas crée cette commandedéfinie comme identique à ''​\relax'' ​; si cette commande n'est pas redéfinie ensuiteelle est conservée inutilement en mémoire par le moteur <​latex>​\TeX{}</​latex>​ ; 
-  * ''​\ifcsname cmd name\endcsname'', ​which does the negative of ''​\@ifundefined''​ without the ''​\relax''​-command side-effect.+  * Si le même nom de commande est testé ensuite avec la primitive ε-TeX ​''​\ifdefined'' ​(par exemple dans le code d'une autre extension), le résultat sera un faux positifcar cette primitive considère aussi comme définie la commande ​''​\relax'' ​et ses alias.
  
-So, in an ε-<​latex>​\TeX{}</​latex>​-based systemthe following two conditional clauses do +Avant que ''​\@ifundefined''​ ne soit redéfinie dans le noyau <​latex>​\LaTeX{}</​latex> ​pour être basée sur la primitive ε-TeX ''​\ifdefined''​David Kastrup a proposé la solution suivante :
-the same thing:+
  
 <code latex> <code latex>
-\ifdefined\foo +{\expandafter}\expandafter\ifx \csname cmd name\endcsname\relax ...
-  \message{\string\foo\space is defined}+
-\else +
-  ​\message{no command ​\string\foo}% +
-\fi +
-+
-\ifcsname foo\endcsname +
-  \message{\string\foo\space is defined}% +
-\else +
-  \message{no command \string\foo}% +
-\fi+
 </​code>​ </​code>​
-However, after using the original LaTeX ''​\@ifundefined{foo}...'',​ 
-the conditionals will detect the command as "​existing"​ 
-(since it has been ''​\let''​ to ''​\relax''​) ; so it is important 
-not to mix mechanisms for detecting the state of a command. 
  
-In the 2018 <​latex>​\LaTeX{}</​latex>​ release, the definition of ''​\@ifundefined'' ​was adapted +La commande testée est créée et définie comme ''​\relax'' ​à l'​intérieur du groupe dans lequel est inclus le premier 
-to use the $\epsilon$-TeX ​''​\ifcsname'' ​and now tests for a command being undefined or ''​\relax''​ +''​\expandafter''​ : elle n'est donc pas conservée en mémoire après l'exécution de ''​\@ifundefined''​.
-without the side effect of defining undefined commands to ''​\relax''​.+
  
 ----- -----
2_programmation/macros/cette_commande_est_elle_definie.txt · Dernière modification: 2021/09/27 23:41 par bdumont
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0