Como usar `\@ifdefinable{xfoo}{...}` quando `\foo` já está definido?

Como usar `\@ifdefinable{xfoo}{...}` quando `\foo` já está definido?

O código a seguir falha na compilação:

\documentclass{article}
\makeatletter
\newcommand{\foo}{xyzzy}

\@ifdefinable{xfoo}{\relax}
\makeatother

\begin{document}
...
\end{document}  

Mais precisamente, falha com o seguinte erro:

LaTeX Error: Command \foo already defined.
Or name \end... illegal, see p.192 of the manual.

Isto deve-se essencialmente à forma como \@ifdefinableé implementado internamente.

Pergunta.Existe uma boa solução alternativa que não envolva renomear \fooou substituir \@ifdefinablepor um comando diferente? (Na minha situação real, \fooé fornecido por um pacote e \@ifdefinableestá sendo usado por outro pacote.)

Responder1

O argumento \@ifdefinabledeve ser uma sequência de controle, não uma sequência de caracteres. O erro é espúrio devido ao fato de que \@ifdefinabletiras o primeiro caractere na forma stringificada do argumento, assumindo que seja uma barra invertida.

Então você deveria fazer

\@ifdefinable{\xfoo}{...}

Talvez você esteja confundindo isso com \@ifundefined: se quiser ver se \fooé indefinido (ou \relax), o teste é

\@ifundefined{foo}{code for undefined}{code for defined}

Este é realmente um bug no aliasctr.sty, onde a linha 59 está

 59       \@ifdefinable{c@#1}{%

e deveria ser

 59       \expandafter\@ifdefinable\csname c@#1\endcsname{%

informação relacionada