在下面的例子中,Hook 1 和 Hook 4 可以编译,但 Hook 2 和 Hook 3 不能。为什么?
\documentclass{report}
\usepackage{xparse}
\ExplSyntaxOn
\prop_set_from_keyval:Nn \__erw_foo_prop{key=a}
\cs_set:Nn \__erw_prop:n {\use:c{__erw_#1_prop}}
\cs_set:Nn \__erw_prop_name:n {__erw_#1_prop}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\prop_item:Nn
%{
\__erw_foo_prop
%}
{key}
\exp_args:Nf\prop_item:Nn
{
\__erw_prop:n{foo}
} {key} % Hook1
%\exp_args:Nf
%\prop_put:Nnn
%{
% \__erw_prop:n{foo}
%}
%{jey}{c}% Hook2
%\exp_last_unbraced:Nf
%\prop_put:Nnn
%{
% \__erw_prop:n{foo}
% {jey}{c}
%}% Hook3
\prop_put:cnn
{
\__erw_prop_name:n{foo}
}
{jey}{c}% Hook4
\exp_args:Nf\prop_item:Nn
{
\__erw_prop:n{foo}
} {jey}
\ExplSyntaxOff
\end{document}
更新:
我希望 Hook 1 可以重现<fun>=put
,这样我就可以想出一个适用于和的元函数item
。put
无论这是否可行,我都想知道是什么导致了 Hook 2 和 Hook 3 的编译错误。
答案1
你应该使用\prop_put:cnn
和\prop_item:cn
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new:Nn \__erwann_prop_name:n { l__erwann_#1_prop }
\cs_new_protected:Nn \erwann_prop_put:nnn
{
\prop_put:cnn { \__erwann_prop_name:n { #1 } } { #2 } { #3 }
}
\cs_new:Nn \erwann_prop_item:nn
{
\prop_item:cn { \__erwann_prop_name:n { #1 } } { #2 }
}
\prop_set_from_keyval:Nn \l__erwann_foo_prop {key=a}
\begin{document}
\erwann_prop_item:nn { foo } { key }
\par
\erwann_prop_put:nnn { foo } { jey } { c }
\erwann_prop_item:nn { foo } { jey }
\end{document}
这将打印
一个
你尝试完成上述工作的方法都违反了expl3
惯例。让我们看看
\exp_args:Nf \prop_item:Nn { \__erw_prop:n {foo} } {key}
变f
体到达后{
开始“扩展到第一个遇到的不可扩展标记”,简称 f 扩展。第一级是
\use:c { __erw_foo_prop }
\__erw_foo_prop
然后变成\s__prop[...]
。它似乎起作用完全是偶然的。
对于尝试 2 和 3 也是如此,因为在这两种情况下,\prop_put:Nnn
它都将\s__prop
其作为第一个参数,但它不知道如何处理它。