
Considere el siguiente ejemplo 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}
El archivo de registro resultante contiene una entrada {retaining \testB=macro:->blubb}
, pero ninguna entrada correspondiente para \testA
. Hasta donde yo entiendo TeX, esto significa que \csname...\endcsname
define la macro \testA
como \relax
localmente, que inmediatamente reasigno globalmente como "blubb", lo que, a su vez, agrega una entrada de retención en mi save_stack.
En mi aplicación del mundo real, necesito poder definir un número potencialmente infinito de macros con nombres individuales usando construcciones csname, lo que ahora ha provocado un desbordamiento de pila debido a esto. (bueno, tal vez no infinito, pero definitivamente más de 80000…)
Mi pregunta ahora es: ¿Hay alguna manera de inicializar una \csname…\endcsname
construcción globalmente para evitar que se apilen en la pila guardada? ¿O algún tipo de solución que mantenga limpia mi pila de guardado?
Respuesta1
En lugar de hacer que la \csname
tarea sea global, puedes hacerla aún más 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}
Ahora \expandafter
se ejecuta en un grupo, por lo que se \csname
define \testB
en \relax
un grupo que termina antes de \gdef
comenzar. Por lo tanto, \testB
no está definido cuando se produce la definición global, lo que debería evitar la entrada de retención.
Respuesta2
No sé nada sobre pilas de (La)TeX (aparte de stackengine
, LOL), pero si el objetivo es evitar tener el \csname
interior un \def
...
Expanda el \csname
antes de ejecutar el exterior \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}