\cs_new:Npn verursacht einen Fehler wegen ungültiger Einheit oder Maßeinheit, während \let dies nicht tut.

\cs_new:Npn verursacht einen Fehler wegen ungültiger Einheit oder Maßeinheit, während \let dies nicht tut.

Im MWE:

\documentclass{article}
\setlength{\fboxsep}{0pt}
\begin{document}

\ExplSyntaxOn
\cs_new:Npn \foo:nn #1#2
  {
    \makebox[#1][s]{#2}
  }
% \cs_new:Npn \bar:nn #1#2 { \foo:nn #1#2 }
\let \bar:nn \foo:nn
\fbox{\foo:nn {3cm} {a~b~c~d}}\par
\fbox{\bar:nn {3cm} {a~b~c~d}}
\ExplSyntaxOff

\end{document}

Wenn ich \cs_new:Npnanstelle von verwende \let, wird die Fehlermeldung „ungültige Maßeinheit“ ausgegeben. Warum? Wie kann ich das beheben?

Antwort1

Es ist ein Problem der TeX-Syntax:

\cs_new:Npn \foo:nn #1#2 { ... }

Ich zeige Ihnendefinieren \foo:nnAber wenn SieAnrufes, müssen Sie tun

\foo:nn {<argument 1>}{<argument 2>}

und die Klammern können weggelassen werden, wenn das Argument aus einem einzelnen Token besteht.

Bei Ihrem Versuch \bar:nn {3cm}{abcd}erhalten Sie

\foo:nn 3cmabcd

so #1ist 3und #2ist c, was zu

\makebox[3][s]{c}mabcd

was definitiv nicht das ist, was Sie wollen. Mit

\cs_new:Npn \bar:nn #1#2 { \foo:nn {#1}{#2} }

Sie erhalten das gewünschte.

Wir haben festgestellt, dass „ \letnicht verwendet werden sollte“, wo es \cs_new_eq:NNsich um den richtigen Aufruf handelt. Vergleichen wir nun die folgenden Aufrufe:

  1. \cs_new:Npn \bar:nn #1#2 { \foo:nn {#1}{#2} }
  2. \cs_new_eq:NN \bar:nn \foo:nn

Gibt es Unterschiede? Viele. Beim ersten Aufruf \bar:nnwird die Bedeutung von verwendet, \foo:nndie zum Aufrufzeitpunkt aktuell ist; beim zweiten Aufruf \bar:nnwird die Bedeutung von verwendet, die \foo:nnzum Definitionszeitpunkt aktuell ist. Sie müssen also wissenWarumman führt eine solche Definition durch und trifft die entsprechende Wahl. Wenn man sicher ist, dass \foo:nnsich die Bedeutung nie ändert, sind die beiden Aufrufe nahezu gleichwertig: nicht ganz gleich, denn bei 1 \bar:nnist ein Expansionsschritt mehr erforderlich als bei 2.

Notiz.Ich habe einige Aspekte außer Acht gelassen, die für das Problem nicht relevant, aber wichtig sind.

  1. expl3Versuchen Sie, die Namenskonventionen einzuhalten : Sowohl \foo:nnals auch \bar:nnsind schlechte Namen.

  2. Funktionen, die nicht erweiterbare Funktionen/Makros verwenden, wie beispielsweise \makebox:

    \cs_new_protected:Npn \stephen_foo:nn #1#2 { \makebox[#1][s]{#2} }
    

    wäre besser.

verwandte Informationen