简单来说,我什么时候应该关心某件事是否是全局的?这到底意味着什么?
例如,如果我的包裹提供
\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)的。test2
l.16
\gdef
l.14
\global
如果需要,也可以在所需的全局定义前面加上。因此,在上面的例子中,使用
\global\mymacro{test1}
将会翻译为
\global\def\myothermacro{test1}
相当于
\gdef\myothermacro{test1}
请注意,有些命令“超越”了组。例如,为什么\setcounter
和\addtocounter
命令具有全局效果,而\setlength
和\addtolength
命令却遵循正常的作用域规则?