\cs_new:Npn は不正な単位または測定エラーを引き起こしますが、\let はそうではありません

\cs_new:Npn は不正な単位または測定エラーを引き起こしますが、\let はそうではありません

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}

\cs_new:Npnの代わりにを使用すると\let、「不正な測定単位」エラーが発生します。なぜでしょうか? これを修正するにはどうすればいいでしょうか?

答え1

これは TeX 構文の問題です:

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

お見せしましょう定義する \foo:nnしかし、あなたが電話それを行う必要があります

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

引数が単一のトークンで構成されている場合は、中括弧を省略できます。

あなたの試みでは、\bar:nn {3cm}{abcd}あなたから

\foo:nn 3cmabcd

#1あり3#2でありc、結果として

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

それは絶対にあなたが望んでいることではありません。

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

望んだものを手に入れます。

正しい呼び出しでは\let使用すべきではないことに気づいたので、次の呼び出しを比較してみましょう。\cs_new_eq:NN

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

何か違いはありますか?たくさんあります。最初の呼び出しでは、呼び出し時の現在の意味を使用します。2番目の呼び出しでは\bar:nn\foo:nn\bar:nn\foo:nn。したがって、次のことを知っておく必要があります。なぜこのような定義を行い、適切な選択を行います。\foo:nn意味が変わらないことが確実であれば、2 つの呼び出しはほぼ同等です。ただし、1 の場合は\bar:nn2 の場合よりも 1 つの拡張ステップが必要になるため、完全に同じではありません。

注記。問題に関係のないいくつかの側面は無視しましたが、それらは重要です。

  1. 命名規則に従ってくださいexpl3。 と\foo:nnはどちらも\bar:nn不適切な名前です。

  2. 次のような展開できない関数/マクロを使用する関数は\makebox「保護」する必要があります。

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

    のほうがいい。

関連情報