
Considere o seguinte exemplo mínimo:
\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}
O arquivo de log resultante contém uma entrada {retaining \testB=macro:->blubb}
, mas nenhuma entrada correspondente para \testA
. Pelo que entendi o TeX, isso significa que \csname...\endcsname
define a macro \testA
como \relax
localmente, que imediatamente após reatribuo globalmente como "blubb", que, por sua vez, adiciona uma entrada de retenção no meu save_stack.
Em meu aplicativo do mundo real, preciso ser capaz de definir um número potencialmente infinito de macros nomeadas individualmente usando construções csname, o que agora levou a um estouro de pilha por causa disso. (bem, talvez não infinito, mas definitivamente mais de 80.000…)
Minha pergunta agora é: existe uma maneira de inicializar um \csname…\endcsname
-construct globalmente para evitar que eles sejam empilhados na pilha de salvamento? Ou algum tipo de solução alternativa que mantenha minha pilha de salvamento limpa?
Responder1
Em vez de tornar a \csname
atribuição global, você pode torná-la ainda mais local:
\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}
Agora o \expandafter
é executado em grupo, então é definido \csname
em um grupo que termina antes de começar. Portanto, é indefinido quando ocorre a definição global, o que deve evitar a retenção da entrada.\testB
\relax
\gdef
\testB
Responder2
Eu não sei nada sobre pilhas (La)TeX (além de stackengine
, LOL), mas se o objetivo é evitar ter o \csname
interior de um \def
...
Expanda o \csname
antes de executar o outer \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}