
Bitte beachten Sie das folgende Minimalbeispiel:
\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}
Die resultierende Protokolldatei enthält einen Eintrag {retaining \testB=macro:->blubb}
, aber keinen entsprechenden Eintrag für \testA
. Soweit ich TeX verstehe, bedeutet dies, dass \csname...\endcsname
das Makro \testA
als \relax
lokal definiert wird, was ich unmittelbar danach global als „blubb“ neu zuweise, was wiederum einen Aufbewahrungseintrag in meinem Save_Stack hinzufügt.
In meiner realen Anwendung muss ich in der Lage sein, eine potenziell unendliche Anzahl individuell benannter Makros mithilfe von CSNAME-Konstruktionen zu definieren, was deswegen jetzt zu einem Stapelüberlauf geführt hat. (Na ja, vielleicht nicht unendlich, aber definitiv mehr als 80.000 …)
Meine Frage ist nun: Gibt es eine Möglichkeit, eine \csname…\endcsname
-Konstruktion global zu initialisieren, um zu verhindern, dass sie auf dem Speicherstapel gestapelt wird? Oder eine Art Workaround, der meinen Speicherstapel sauber hält?
Antwort1
Anstatt die \csname
Zuweisung global vorzunehmen, können Sie sie auch noch lokaler gestalten:
\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}
Da die \expandafter
Ausführung in einer Gruppe erfolgt, ist die \csname
Definition \testB
in \relax
einer Gruppe, die endet, bevor \gdef
sie beginnt. Daher \testB
ist die globale Definition undefiniert, wodurch der beibehaltene Eintrag vermieden werden sollte.
Antwort2
Ich weiß überhaupt nichts über (La)TeX-Stapel (außer stackengine
, LOL), aber wenn das Ziel darin besteht, zu vermeiden, dass im \csname
Inneren ein \def
...
Erweitern Sie das \csname
, bevor Sie das Äußere ausführen \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}