\globale Variante von \csname…\endcsname

\globale Variante von \csname…\endcsname

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...\endcsnamedas Makro \testAals \relaxlokal 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 \csnameZuweisung 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 \expandafterAusführung in einer Gruppe erfolgt, ist die \csnameDefinition \testBin \relaxeiner Gruppe, die endet, bevor \gdefsie beginnt. Daher \testBist 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 \csnameInneren 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}

verwandte Informationen