`\foo` がすでに定義されている場合に `\@ifdefinable{xfoo}{...}` を使用するにはどうすればよいでしょうか?

`\foo` がすでに定義されている場合に `\@ifdefinable{xfoo}{...}` を使用するにはどうすればよいでしょうか?

次のコードはコンパイルに失敗します。

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

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

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

より正確には、次のエラーで失敗します。

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

\@ifdefinableこれは基本的に、内部的に実装される方法によるものです。

質問。\foo名前を変更したり、\@ifdefinable別のコマンドに置き換えたりせずに済む、良い回避策はありますか? (私の実際の状況では、\fooあるパッケージによって提供され、\@ifdefinable別のパッケージによって使用されています。)

答え1

の引数は\@ifdefinable、文字列ではなく制御シーケンスである必要があります。引数の文字列化された形式の最初の文字がバックスラッシュであると想定して削除されるため、このエラーは誤ってい\@ifdefinableます。

だからあなたは

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

おそらくこれを と混同しているでしょう。が未定義(または)\@ifundefinedかどうかを確認したい場合、テストは次のようになります。\foo\relax

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

これは確かに のバグでありaliasctr.sty、59行目は

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

そしてそれは

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

関連情報