expl3 の「偽の」バリアント

expl3 の「偽の」バリアント

3つのトークンを操作する関数があるとします。

\cs_new:Nn \@@_on_three:NNN { #1, #2, #3 }

そして、次の 3 つのトークンが値となる変数があります。

\tl_set:Nn \l@@_three_tl { foo }

そして、あなたは変種が欲しいのです

\@@_on_three:V

そうすれば

\@@_on_three:V \l@@_three_tl

しかし、私が間違っていなければ、直接引数は引数の数の違い(またはと)\cs_generate_variantによって混乱し、いずれにしても展開された引数が渡される。NNNVx括弧内、 右?

したがって、必要なのは、次のように定義される一種の「偽の」バリアントです。

\cs_new:Nn \@@_on_three:V
  { \exp_last_unbraced:Nx \@@_on_three:NNN #1 }

明確に言うと:これはうまくいく私の疑問は、むしろ、これより「いたずら」ではない、つまり中程度のトリックではない別の方法があったかどうかですexpl3

答え1

定義

\cs_new:Nn \@@_on_three:V
  { \exp_last_unbraced:Nx \@@_on_three:NNN #1 }

プログラミングのガイドラインではexpl3「間違っている」。V-型のバリアントは -型の基底関数に関連付けられるべきでありn、処理される変数の内容について仮定すべきではない。たとえば、

\tl_set:Nn \l_@@_three_tl { A }

givenの定義とは何\@@_on_three:Vですか? また、x-type 展開ではなくV-type 展開を使用しているため、渡された変数が TeX レジスタである場合や、LaTeX2e の「保護された」コードなどが含まれている場合は失敗します。

明確に言うと、\cs_generate_variant:Nnバリアントを作成するために を使用することは必須ではありませんが、 を使用した場合と同じように動作することが「必須」です。たとえば にはさまざまな手動調整バリアントがありますl3tlが、これはパフォーマンスを向上させるためだけのものであり、動作を変更するものではありません。この点で正しい結果を示さなかったため、最近多くの 型バリアントを強化したという事実も参照してくださいx

質問には書かれていませんが、ここはtl3つのトークンで構成される構造化データを保存するために使用されているようです。したがって、必要なのは次のようになります。

\cs_new:Nn \@@_on_three:N
  { \exp_last_unbraced:No \@@_on_three:NNN #1 }

ここで、セマンティクスは、ちょうど 3 つのトークンを含む\@@_on_three:Nで使用されるべきであるということです。これは低レベルの作業では一般的であり、同様のコードが、たとえば実験的な出力ルーチン ( ) (私が修正することになっている)tlの一部で使用されています。xor

関連情報