当我希望某个宏(暂时)不执行任何操作时,我通常会写
\let\foo\relax
但有人问我为什么不直接这样做
\def\foo{}
我意识到我无法回答他的问题。
因此,我有两个问题:
- 有人能给出一个实际的例子来说明两者在什么情况下会有所不同吗?
- 为了禁用宏,两者中哪一个是首选?
下面是我通常使用方法的一个例子:
\let\print@style\relax
\def\setprintstyle#1{\def\print@style{#1}}
\def\print#1{\print@style#1}
答案1
当你
\def\foo{}
你给出了\foo
一个空定义,但\foo
使用任何用于此目的的测试(例如\ifdefined
或 LaTeX 的\@ifundefined
)仍然“存在”。通过执行以下操作可以实现相同的效果
\let\foo\empty
它的效率略高一些,因为它指向一个已经使用的内存位置(现在不用担心)。当\foo
有这样的定义时,它是可扩展的,所以
\edef\baz{\foo}
将会变得\baz
空洞,因为\foo
扩展为毫无意义。
另一方面
\let\foo\relax
使\foo
等于\relax
原语。这是一个“不做任何事”的操作,但重要的是不是可扩展。因此在这种情况下
\edef\baz{\foo}
保留\baz
定义 ' \foo
'。这可能很有用:这是一种暂时阻止宏执行任何操作同时保留其在其他代码中出现的方式。另一方面,有时您不希望这样:这取决于上下文。当\foo
等于时\relax
,各种测试是否将其视为“存在”更加多变。TeX 会\relax
在各种情况下自动创建等于的控制序列,因此某些测试会将任何等于的内容视为\relax
“未定义”。
因此哪个更好取决于您的使用情况。
答案2
第一个让\foo
指向\relax
,而第二个指向一个空宏。(前提是没有人重新定义\relax
或\empty
。)
\documentclass{article}
\begin{document}
\let\foo\relax
\ifx\foo\relax True\fi
\def\foo{}
\ifx\foo\empty True \fi
\end{document}
为了取消定义,不建议使用
\let\foo\@undefined
在任何阶段你都可以通过以下方式进行测试\meaning
\let\foo\relax
\meaning\foo
将会呈现\relax
编辑
根据修改后的问题。要暂时禁用命令,请放松在组内如图所示:
\def\foo{AAAAAA}
{\let\foo\relax \foo}
\foo
在组内,该命令的含义将等同于\relax
不执行任何操作。在组外,它将恢复其值。