\csname 的 \global 变体…\endcsname

\csname 的 \global 变体…\endcsname

请考虑以下最小示例:

\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}

相关内容