\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-constructions 定義可能無限數量的單獨命名的宏,因此現在導致堆疊溢位。 (嗯,也許不是無限,但絕對超過 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。當全域定義發生時, so\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}

相關內容