请考虑以下最小示例:
\documentclass{article}
\tracingrestores=1
\def\foo{\bar\foobar}
\def\bar{\gdef\testA{blabb}}
\def\foobar{\expandafter\gdef\csname testB\endcsname{blubb}}
\begin{document}
{\foo}
\testA
\testB
\end{document}
生成的日志文件包含一个条目{retaining \testB=macro:->blubb}
,但没有对应的条目\testA
。据我了解,TeX,这意味着\csname...\endcsname
将宏定义\testA
为\relax
本地宏,我立即将其全局重新分配为“blubb”,这反过来又在我的 save_stack 上添加了一个保留条目。
在我的实际应用中,我需要能够使用 csname 构造定义可能无限数量的单独命名的宏,这现在导致了堆栈溢出。(好吧,也许不是无限的,但肯定超过 80000 个……)
我现在的问题是:有没有办法\csname…\endcsname
全局初始化 -construct 以避免它们被堆叠在保存堆栈上?或者某种解决方法可以让我的保存堆栈保持干净?
答案1
除了使分配\csname
更具全局性之外,您还可以使其更加本地化:
\documentclass{article}
\tracingrestores=1
\def\foo{\bar\foobar}
\def\bar{\gdef\testA{blabb}}
\def\foobar{\begingroup\expandafter\endgroup\expandafter\gdef\csname testB\endcsname{blubb}}
\begin{document}
{\foo}
\testA
\testB
\end{document}
现在\expandafter
在组中执行,因此在开始之前结束的组中\csname
定义\testB
为。因此当全局定义发生时未定义,这应该避免保留条目。\relax
\gdef
\testB
答案2
我对 (La)TeX 堆栈一无所知(除了stackengine
,哈哈),但如果目标是避免在\csname
内部出现\def
...
\csname
在执行外部之前展开\def
。
\documentclass{article}
\tracingrestores=1
\def\foo{\bar\foobar}
\def\bar{\gdef\testA{blabb}}
\expandafter\def\expandafter\foobar\expandafter{\expandafter\gdef\csname testB\endcsname{blubb}}
\begin{document}
{\foo}
\testA
\testB
\end{document}