Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente Prochaine révision Les deux révisions suivantes | ||
2_programmation:macros:cette_commande_est_elle_definie [2018/06/03 15:15] joseph.wright |
2_programmation:macros:cette_commande_est_elle_definie [2021/01/07 19:07] jejust Ancienne révision (2020/12/09 20:57) restaurée |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | --- | + | ====== Is this command defined? ====== |
- | title: Is this command defined? | + | |
- | category: programming | + | |
- | tags: macros | + | |
- | permalink: /FAQ-isdef | + | |
- | --- | + | |
Macro sets from the earliest days of TeX programming may be | Macro sets from the earliest days of TeX programming may be | ||
observed to test whether commands exist by using | observed to test whether commands exist by using | ||
- | `\ifx\<command>\undefined` ‹_stuff_› … | + | ''\ifx\<command>\undefined'' <//stuff//> ... |
- | (which of course actually tests that the command _doesn't_ | + | (which of course actually tests that the command //doesn't// |
exist). LaTeX programmers can make use of the internal command | exist). LaTeX programmers can make use of the internal command | ||
- | `\@ifundefined{cmd name}{action1}{action2}` | + | ''\@ifundefined{cmd name}{action1}{action2}'' |
- | which executes `action1` if the command is undefined, and | + | which executes ''action1'' if the command is undefined, and |
- | `action2` if it is defined | + | ''action2'' if it is defined |
- | (_cmd name_ is the command name only, omitting the `\` character). | + | (//cmd name// is the command name only, omitting the ''\'' character). |
+ | |||
+ | The ''\@ifundefined'' command is based on the sequence | ||
- | The `\@ifundefined` command is based on the sequence | + | <code latex> |
- | ```latex | + | |
\expandafter \ifx \csname cmd name\endcsname \relax | \expandafter \ifx \csname cmd name\endcsname \relax | ||
- | ``` | + | </code> |
- | which relies on the way `\csname` works: if the command doesn't | + | which relies on the way ''\csname'' works: if the command doesn't |
- | exist, it simply creates it as an alias for `\relax`. | + | exist, it simply creates it as an alias for ''\relax''. |
So: what is wrong with these techniques? | So: what is wrong with these techniques? | ||
- | Using `\undefined` blithely assumes that the command is indeed not | + | Using ''\undefined'' blithely assumes that the command is indeed not |
defined. This isn't entirely safe; one could make the name more | defined. This isn't entirely safe; one could make the name more | ||
improbable, but that may simply make it more difficult to spot a | improbable, but that may simply make it more difficult to spot a | ||
problem when things go wrong. LaTeX programmers who use the | problem when things go wrong. LaTeX programmers who use the | ||
- | technique will typically employ `\@undefined`, adding a single | + | technique will typically employ ''\@undefined'', adding a single |
level of obscurity. | level of obscurity. | ||
- | The original `\@ifundefined` mechanism had the unfortunate property of | + | The original ''\@ifundefined'' mechanism had the unfortunate property of |
polluting the name space: each test that turns out undefined adds a | polluting the name space: each test that turns out undefined adds a | ||
- | name to the set TeX is holding, and often all those `\relax` | + | name to the set TeX is holding, and often all those ''\relax'' |
names serve no purpose whatever. | names serve no purpose whatever. | ||
David Kastrup offers the (rather tricky) | David Kastrup offers the (rather tricky) | ||
- | ```latex | + | |
+ | <code latex> | ||
{\expandafter}\expandafter\ifx \csname cmd name\endcsname\relax ... | {\expandafter}\expandafter\ifx \csname cmd name\endcsname\relax ... | ||
- | ``` | + | </code> |
- | which "creates" the `\relax`-command inside the group of the first | + | which "creates" the ''\relax''-command inside the group of the first |
- | `\expandafter`, therefore forgets it again once the test is done. | + | ''\expandafter'', therefore forgets it again once the test is done. |
The test is about as good as you can do with macros. | The test is about as good as you can do with macros. | ||
- | The [ε-TeX system](FAQ-etex) system comes to our help here: it | + | The [[FAQ-etex|ε-TeX system]] system comes to our help here: it |
defines two new primitives: | defines two new primitives: | ||
| | ||
- | - `\ifdefined`, which tests whether a thing is defined (the | + | * ''\ifdefined'', which tests whether a thing is defined (the negative of comparing with ''\undefined'', as it were), and |
- | negative of comparing with `\undefined`, as it were), and | + | * ''\ifcsname cmd name\endcsname'', which does the negative of ''\@ifundefined'' without the ''\relax''-command side-effect. |
- | - `\ifcsname cmd name\endcsname`, which does the | + | |
- | negative of `\@ifundefined` without the `\relax`-command | + | |
- | side-effect. | + | |
- | So, in an ε-TeX-based system, the following two conditional clauses do | + | So, in an <latex>$\epsilon$-\TeX{}</latex>-based system, the following two conditional clauses do |
the same thing: | the same thing: | ||
- | ```latex | + | |
+ | <code latex> | ||
\ifdefined\foo | \ifdefined\foo | ||
\message{\string\foo\space is defined}% | \message{\string\foo\space is defined}% | ||
Ligne 69: | Ligne 65: | ||
\message{no command \string\foo}% | \message{no command \string\foo}% | ||
\fi | \fi | ||
- | ``` | + | </code> |
However, after using the original LaTeX | However, after using the original LaTeX | ||
- | `\@ifundefined{foo}`…, the conditionals will detect the | + | ''\@ifundefined{foo}''..., the conditionals will detect the |
- | command as "existing" (since it has been `\let` to `\relax`); | + | command as "existing" (since it has been ''\let'' to ''\relax''); |
so it is important not to mix mechanisms for detecting the state of a | so it is important not to mix mechanisms for detecting the state of a | ||
command. | command. | ||
- | In the 2016 LaTeX release, the definition of `\@ifundefined` was adapted | + | In the 2018 <latex>\LaTeX{}</latex> release, the definition of ''\@ifundefined'' was adapted |
- | to use the ε-TeX `\ifcsname` and now tests for a command being undefined or `\relax` | + | to use the $\epsilon$-TeX ''\ifcsname'' and now tests for a command being undefined or ''\relax'' |
- | without the side effect of defining undefined commands to `\relax`. | + | without the side effect of defining undefined commands to ''\relax''. |
+ | |||
+ | ----- | ||
+ | //Source:// [[faquk>FAQ-isdef|Is this command defined?]] | ||
+ | |||
+ | {{htmlmetatags>metatag-keywords=(LaTeX,programmation LaTeX,tester si une macro est définie,savoir si une commande est définie) | ||
+ | metatag-og:title=(Is this command defined?) | ||
+ | metatag-og:site_name=(FAQ LaTeX francophone) | ||
+ | }} | ||