\variante global de \csname…\endcsname

\variante global de \csname…\endcsname

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...\endcsnamedefine la macro \testAcomo \relaxlocalmente, 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…\endcsnameconstrucció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 \csnametarea 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 \expandafterse ejecuta en un grupo, por lo que se \csnamedefine \testBen \relaxun grupo que termina antes de \gdefcomenzar. Por lo tanto, \testBno 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 \csnameinterior un \def...

Expanda el \csnameantes 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}

información relacionada