Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I thought the way to undo a \def was to define it to \relax, but that does not appear to work. Also, am not sure why this produces no output if I try to use \def instead of \let in my attempt to do an undef.

\documentclass{article}

\begin{document}

\def\CaseA{}%

\ifdefined\CaseA%
    \def\ProcessCaseA{}%
    % Do stuff that uses \ProcessCaseA
    %\def\ProcessCaseA\relax% no output if use this, and comment next line
    \let\ProcessCaseA\relax% no output if comment this, and use above line
\fi

% Now do stuff that requires \ProcessCaseA NOT be defined
\ifdefined\ProcessCaseA
    ERROR: \textbackslash ProcessCaseA is still defined
\else
    SUCCESS: \textbackslash ProcessCaseA is not defined
\fi

\end{document}
share|improve this question

4 Answers 4

up vote 9 down vote accepted

The macro \ifdefined is not part of basic TeX, so I suppose you are getting it from eTeX. In that case, you should consider using the etoolbox package, which provides a few wrapper functions \ifdef{\macro}{true}{false} and \ifundef{\macro}{true}{false}. The etoolbox manual tells me that the latter has the convenient effect of registering a macro \let to \relax as being "undefined", which sounds like what you want.

Alternatively, depending on the situation, if you truly wish to erase a macro from TeX's memory, you can define it in a group and then leave the group. Note that this is quite different from \letting it to \relax, since if TeX tries to read \macro before it has ever been \def'd or \let, it will raise an error, while if you have written \let\macro=\relax, it will just do nothing.

share|improve this answer
    
Adding \begingroup and \endgroup worked great. Thanks. –  Peter Grill Jun 14 '11 at 0:22
5  
etoolbox also has \undef. –  Philipp Jun 14 '11 at 5:27
    
@Philipp: so it does! I never went to that section of the manual. –  Ryan Reich Jun 14 '11 at 13:53

You need to let it to undefined, not relax, try this

\providecommand*\@nameundef[1]{%
  \expandafter\let\csname #1\endcsname\@undefined}

See comments by Ulrich below for some caveats.

share|improve this answer
4  
... conditional on the fact that no control sequence named \@undefined is defined. (But I think that's assumed at some places in the kernel as well, so \def\@undefined{} would likely break a lot of stuff anyway, so the user will notice.) –  Ulrich Schwarz Jun 14 '11 at 7:09
4  
@UlrichSchwarz The command \@undefined is used more than 800 times in my texmf tree, so it is a good assumption. –  tohecz Mar 6 '12 at 10:23

The assignment \let\xyz\relax makes \xyz "undefined" as far as the \@ifundefined test is concerned. So

\makeatletter
\let\xyz\relax
\@ifundefined{xyz}{LaTeX undefined}{LaTeX defined}\par
\ifdefined\xyz e-TeX defined\else e-TeX undefined\fi\par
\ifcsname xyz\endcsname e-TeX defined\else e-TeX undefined\fi\par

would print

LaTeX undefined
e-TeX defined
e-TeX defined

The only safe way to "undefine" a command is to define it inside a group: at the end of it the definition will vanish. There is \undef in etoolbox that relies on the fact that a specific control sequence (\etb@undefined) will never be defined by anybody.

Choosing between the \@ifundefined and \ifdefined tests is a matter of convenience and mostly depends on what you need. Notice that the argument to \@ifundefined is the macro's name, without the backslash.

share|improve this answer
    
@tohecz It undefines the command, unless \@undefined has received a meaning. It's the same as etoolbox's \undef. –  egreg Nov 24 '13 at 0:03

\let\ProcessCaseA\relax% no output if comment this, and use above line

You should be using \global\let here rather than \let.

share|improve this answer
    
This does not seem to a make a difference. I still get the same results. I had tried \gdef before but that does not produce any output (same problem as documented in the comments of the MWE). –  Peter Grill Jun 14 '11 at 0:18
4  
There's no reason to use \global here. Conditionals do not create a group. –  TH. Jun 14 '11 at 1:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.