全球混乱

全球混乱

简单来说,我什么时候应该关心某件事是否是全局的?这到底意味着什么?

例如,如果我的包裹提供

\newcommand*{\setfooter}[1]{\def\mypackage@footer{#1}}

然后我又\mypackage@footer在包装里面使用了,我使用了\def而不是使用了,这样正确吗\gdef

附加到\maketitle,为什么我要使用\gappto{\maketitle}{\thispagestyle{fancy}}\gappto来自etoolbox,相当于\g@addto@macro),而不是简单地使用\appto,当两者似乎都有效时?(来自这个答案

答案1

如果你发出

\setfooter{foo}

在顶层,不在组或环境内部(document在这方面不算作环境),没有区别。

然而,输入如下

{\setfooter{foo}}

会导致\mypackage@footer 不是一旦扫描到右括号,就不再进行定义。

如果您怀疑您的软件包的用户可能会\setfooter在群组中发出问题,那么使用\gdef

为什么使用\gappto而不是\appto?这是相同的原因。我建议在两种情况下都使用“全局”,这样就不会出现不明显的故障。

在您链接的答案中,Werner 使用是\g@addto@macro因为 LaTeX 内核没有提供“本地”等效项。

答案2

宏定义被视为给定“宏和参数”的“替换文本”。因此,使用如下定义

\newcommand*{\setfooter}[1]{\def\mypackage@footer{#1}}

\setfooter代码中的 的使用被 替换\def\mypackage@footer{#1}。如果\setfooter不在组内,则\def\mypackage@footer{#1}也将不在该组内。因此,如果宏及其最终替换的使用不是全局(组外)所必需的,则无需全局声明它(使用\gdef\xdef)。

下面是一个强调上述讨论的小例子:

\documentclass{article}
\newcommand{\mymacro}[1]{\def\myothermacro{#1}}
\newcommand{\mygmacro}[1]{\gdef\myothergmacro{#1}}
\begin{document}
\begingroup% Start a group
\mymacro{test1}% Local definition of \myothermacro as test1
\endgroup% End a group
\show\myothermacro% \myothermacro is undefined
\mymacro{test1}% Local definition of \myothermacro as test1
\show\myothermacro% \myothermacro is defined as test1
\myothermacro% test1

\begingroup% Start a group
\mygmacro{test2}% Global definition of \myothergmacro as test2
\endgroup% End a group
\show\myothergmacro% \myothergmacro is defined as test2
\mygmacro{test2}% Global definition of \myothergmacro as test2
\show\myothergmacro% \myothergmacro is defined as test2
\myothergmacro% test2
\end{document}​

输出.log结果为

> \myothermacro=undefined.
l.8 \show\myothermacro


> \myothermacro=macro:
->test1.
l.10 \show\myothermacro


> \myothergmacro=macro:
->test2.
l.16 \show\myothergmacro


> \myothergmacro=macro:
->test2.
l.18 \show\myothergmacro

请注意,\myothermacro在 上未定义l.8,因为它的定义是在 上的局部定义l.6(在组内)。但是,在 上\myothergmacro定义为,因为它是在 上全局定义(或-ed)的。test2l.16\gdefl.14

\global如果需要,也可以在所需的全局定义前面加上。因此,在上面的例子中,使用

\global\mymacro{test1}

将会翻译为

\global\def\myothermacro{test1}

相当于

\gdef\myothermacro{test1}

请注意,有些命令“超越”了组。例如,为什么\setcounter\addtocounter命令具有全局效果,而\setlength\addtolength命令却遵循正常的作用域规则?

相关内容