
Пожалуйста, рассмотрите следующий минимальный пример:
\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
, LOL), но если цель состоит в том, чтобы избежать наличия \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}