
Angenommen, Sie haben eine Funktion, die mit drei Token arbeitet,
\cs_new:Nn \@@_on_three:NNN { #1, #2, #3 }
Und Sie haben eine Variable, deren Wert die drei Token sind:
\tl_set:Nn \l@@_three_tl { foo }
Und Sie möchten eine Variante
\@@_on_three:V
damit du sagen kannst
\@@_on_three:V \l@@_three_tl
Wenn ich mich jedoch nicht irre, \cs_generate_variant
würde eine direkte Anweisung durch die unterschiedliche Anzahl von Argumenten ( NNN
vs. V
oder x
) verwirrt werden und in jedem Fall das erweiterte Argument übergeben.in Klammern, Rechts?
Was Sie also brauchen, ist eine Art „gefälschte“ Variante, die wie folgt definiert ist:
\cs_new:Nn \@@_on_three:V
{ \exp_last_unbraced:Nx \@@_on_three:NNN #1 }
Deutlich sein:das funktioniert. Meine Frage ist eher, ob es eine andere Möglichkeit gibt, dies zu tun, die weniger „ungezogen“ ist – weniger Tricksereien auf mittlerer Ebene expl3
.
Antwort1
Die Definition
\cs_new:Nn \@@_on_three:V
{ \exp_last_unbraced:Nx \@@_on_three:NNN #1 }
ist nach den Richtlinien der expl3
Programmierung „falsch“. Eine V
-Typ-Variante sollte mit einer -Typ-unterliegenden Funktion in Beziehung stehen n
und sollte keine Annahmen über den Inhalt der verarbeiteten Variable treffen. Was passiert beispielsweise mit
\tl_set:Nn \l_@@_three_tl { A }
mit der Definition von \@@_on_three:V
gegeben? Außerdem führen Sie x
eine -Typ-Erweiterung statt V
einer -Typ-Erweiterung durch, was beispielsweise fehlschlägt, wenn die übergebene Variable ein TeX-Register ist oder wenn sie so etwas wie „geschützten“ LaTeX2e-Code enthält.
Um es klar zu sagen: Es ist nicht erforderlich, dass Sie \cs_generate_variant:Nn
Varianten erstellen, aber es ist „erforderlich“, dass sie sich genauso verhalten, als ob sie es wären. Es gibt verschiedene manuell angepasste Varianten in beispielsweise l3tl
, aber dies dient nur der Leistungsverbesserung und ändert das Verhalten nicht. Beachten Sie auch die Tatsache, dass wir kürzlich viele x
Varianten vom Typ verschärft haben, da sie in dieser Hinsicht nicht die richtigen Ergebnisse zeigten.
Die Frage sagt es nicht, aber es liest sich, als ob tl
hier einige strukturierte Daten gespeichert werden, die immer aus drei Token bestehen. Was also gewünscht scheint, ist
\cs_new:Nn \@@_on_three:N
{ \exp_last_unbraced:No \@@_on_three:NNN #1 }
wobei die Semantik \@@_on_three:N
mit einem verwendet werden sollte, das tl
genau drei Token enthält. Dies ist bei Low-Level-Arbeiten üblich, und ähnlicher Code wird beispielsweise in Teilen der experimentellen Ausgaberoutine ( xor
) verwendet (die ich überarbeiten soll).