\глобальный вариант \csname…\endcsname

\глобальный вариант \csname…\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, 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}

Связанный контент